mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge pull request #67 from abollini/DS-1218
DS-1218 BrowseDAO based on discovery
This commit is contained in:
@@ -29,19 +29,34 @@ public class BrowseDAOFactory
|
||||
public static BrowseDAO getInstance(Context context)
|
||||
throws BrowseException
|
||||
{
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
if ("postgres".equals(db))
|
||||
{
|
||||
return new BrowseDAOPostgres(context);
|
||||
}
|
||||
else if ("oracle".equals(db))
|
||||
{
|
||||
return new BrowseDAOOracle(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BrowseException("The configuration for db.name is either invalid, or contains an unrecognised database");
|
||||
}
|
||||
String className = ConfigurationManager.getProperty("browseDAO.class");
|
||||
if (className == null)
|
||||
{
|
||||
// For compatibility with previous versions
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
if ("postgres".equals(db))
|
||||
{
|
||||
return new BrowseDAOPostgres(context);
|
||||
}
|
||||
else if ("oracle".equals(db))
|
||||
{
|
||||
return new BrowseDAOOracle(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BrowseException("The configuration for db.name is either invalid, or contains an unrecognised database");
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
return (BrowseDAO) Class
|
||||
.forName(ConfigurationManager.getProperty("browseDAO.class"))
|
||||
.getConstructor(Context.class).newInstance(context);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new BrowseException("The configuration for browseDAO is invalid: "+className, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,19 +70,34 @@ public class BrowseDAOFactory
|
||||
public static BrowseCreateDAO getCreateInstance(Context context)
|
||||
throws BrowseException
|
||||
{
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
if ("postgres".equals(db))
|
||||
{
|
||||
return new BrowseCreateDAOPostgres(context);
|
||||
}
|
||||
else if ("oracle".equals(db))
|
||||
{
|
||||
return new BrowseCreateDAOOracle(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BrowseException("The configuration for db.name is either invalid, or contains an unrecognised database");
|
||||
}
|
||||
String className = ConfigurationManager.getProperty("browseCreateDAO.class");
|
||||
if (className == null)
|
||||
{
|
||||
// For compatibility with previous versions
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
if ("postgres".equals(db))
|
||||
{
|
||||
return new BrowseCreateDAOPostgres(context);
|
||||
}
|
||||
else if ("oracle".equals(db))
|
||||
{
|
||||
return new BrowseCreateDAOOracle(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BrowseException("The configuration for db.name is either invalid, or contains an unrecognised database");
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
return (BrowseCreateDAO) Class
|
||||
.forName(ConfigurationManager.getProperty("browseCreateDAO.class"))
|
||||
.getConstructor(Context.class).newInstance(context);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new BrowseException("The configuration for browseCreateDAO is invalid: "+className, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.content.authority;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* This is a *very* stupid test fixture for authority control with AuthorityVariantsSupport.
|
||||
*
|
||||
* @author Andrea Bollini (CILEA)
|
||||
*/
|
||||
public class TestAuthority implements ChoiceAuthority, AuthorityVariantsSupport
|
||||
{
|
||||
|
||||
@Override
|
||||
public List<String> getVariants(String key, String locale)
|
||||
{
|
||||
if (StringUtils.isNotBlank(key))
|
||||
{
|
||||
List<String> variants = new ArrayList<String>();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
variants.add(key+"_variant#"+i);
|
||||
}
|
||||
return variants;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Choices getMatches(String field, String text, int collection,
|
||||
int start, int limit, String locale)
|
||||
{
|
||||
Choices choices = new Choices(false);
|
||||
if (StringUtils.isNotBlank(text))
|
||||
{
|
||||
|
||||
List<Choice> choiceValues = new ArrayList<Choice>();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
choiceValues.add(new Choice(text + "_authority#" + i, text
|
||||
+ "_value#" + i, text + "_label#" + i));
|
||||
}
|
||||
choices = new Choices(
|
||||
(Choice[]) choiceValues.toArray(new Choice[choiceValues
|
||||
.size()]), 0, 3, Choices.CF_AMBIGUOUS, false);
|
||||
}
|
||||
|
||||
return choices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Choices getBestMatch(String field, String text, int collection,
|
||||
String locale)
|
||||
{
|
||||
Choices choices = new Choices(false);
|
||||
if (StringUtils.isNotBlank(text))
|
||||
{
|
||||
|
||||
List<Choice> choiceValues = new ArrayList<Choice>();
|
||||
|
||||
choiceValues.add(new Choice(text + "_authoritybest", text
|
||||
+ "_valuebest", text + "_labelbest"));
|
||||
|
||||
choices = new Choices(
|
||||
(Choice[]) choiceValues.toArray(new Choice[choiceValues
|
||||
.size()]), 0, 3, Choices.CF_UNCERTAIN, false);
|
||||
}
|
||||
return choices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel(String field, String key, String locale)
|
||||
{
|
||||
if (StringUtils.isNotBlank(key))
|
||||
{
|
||||
return key.replaceAll("authority", "label");
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
@@ -110,11 +110,15 @@ public class DiscoverResult {
|
||||
public static final class FacetResult{
|
||||
private String asFilterQuery;
|
||||
private String displayedValue;
|
||||
private String authorityKey;
|
||||
private String sortValue;
|
||||
private long count;
|
||||
|
||||
public FacetResult(String asFilterQuery, String displayedValue, long count) {
|
||||
public FacetResult(String asFilterQuery, String displayedValue, String authorityKey, String sortValue, long count) {
|
||||
this.asFilterQuery = asFilterQuery;
|
||||
this.displayedValue = displayedValue;
|
||||
this.authorityKey = authorityKey;
|
||||
this.sortValue = sortValue;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@@ -126,9 +130,19 @@ public class DiscoverResult {
|
||||
return displayedValue;
|
||||
}
|
||||
|
||||
public String getSortValue()
|
||||
{
|
||||
return sortValue;
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public String getAuthorityKey()
|
||||
{
|
||||
return authorityKey;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class DSpaceObjectHighlightResult
|
||||
|
@@ -25,10 +25,76 @@ import java.util.List;
|
||||
*/
|
||||
public interface SearchService {
|
||||
|
||||
DiscoverResult search(Context context, DiscoverQuery query) throws SearchServiceException;
|
||||
/**
|
||||
* Convenient method to call @see #search(Context, DSpaceObject,
|
||||
* DiscoverQuery) with a null DSpace Object as scope (i.e. all the
|
||||
* repository)
|
||||
*
|
||||
* @param context
|
||||
* DSpace Context object
|
||||
* @param dso
|
||||
* a DSpace Object to use as scope of the search (only results
|
||||
* within this object)
|
||||
* @param query
|
||||
* the discovery query object
|
||||
* @return
|
||||
* @throws SearchServiceException
|
||||
*/
|
||||
DiscoverResult search(Context context, DiscoverQuery query)
|
||||
throws SearchServiceException;
|
||||
|
||||
DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery query) throws SearchServiceException;
|
||||
/**
|
||||
* Convenient method to call @see #search(Context, DSpaceObject,
|
||||
* DiscoverQuery, boolean) with includeWithdrawn=false
|
||||
*
|
||||
* @param context
|
||||
* DSpace Context object
|
||||
* @param dso
|
||||
* a DSpace Object to use as scope of the search (only results
|
||||
* within this object)
|
||||
* @param query
|
||||
* the discovery query object
|
||||
* @return
|
||||
* @throws SearchServiceException
|
||||
*/
|
||||
DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery query)
|
||||
throws SearchServiceException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
* DSpace Context object
|
||||
* @param dso
|
||||
* a DSpace Object to use as scope of the search (only results
|
||||
* within this object)
|
||||
* @param includeWithdrawn
|
||||
* use <code>true</code> to include in the results also withdrawn
|
||||
* items that match the query
|
||||
* @return
|
||||
* @throws SearchServiceException
|
||||
*/
|
||||
DiscoverResult search(Context context, DiscoverQuery query,
|
||||
boolean includeWithdrawn) throws SearchServiceException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
* DSpace Context object
|
||||
* @param dso
|
||||
* a DSpace Object to use as scope of the search (only results
|
||||
* within this object)
|
||||
* @param query
|
||||
* the discovery query object
|
||||
* @param includeWithdrawn
|
||||
* use <code>true</code> to include in the results also withdrawn
|
||||
* items that match the query
|
||||
*
|
||||
* @return
|
||||
* @throws SearchServiceException
|
||||
*/
|
||||
DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery query, boolean includeWithdrawn) throws SearchServiceException;
|
||||
|
||||
|
||||
InputStream searchJSON(Context context, DiscoverQuery query, String jsonIdentifier) throws SearchServiceException;
|
||||
|
||||
InputStream searchJSON(Context context, DiscoverQuery query, DSpaceObject dso, String jsonIdentifier) throws SearchServiceException;
|
||||
@@ -36,6 +102,7 @@ public interface SearchService {
|
||||
|
||||
List<DSpaceObject> search(Context context, String query, String orderfield, boolean ascending, int offset, int max, String... filterquery);
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the given string field and value into a filter query
|
||||
* @param context the DSpace context
|
||||
@@ -46,7 +113,7 @@ public interface SearchService {
|
||||
*/
|
||||
DiscoverFilterQuery toFilterQuery(Context context, String field, String operator, String value) throws SQLException;
|
||||
|
||||
List<Item> getRelatedItems(Context context, Item item, DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration);
|
||||
List<Item> getRelatedItems(Context context, Item item, DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration);
|
||||
|
||||
/**
|
||||
* Transforms the metadata field of the given sort configuration into the indexed field which we can then use in our solr queries
|
||||
|
@@ -0,0 +1,533 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.browse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.authority.ChoiceAuthorityManager;
|
||||
import org.dspace.content.authority.MetadataAuthorityManager;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.SolrServiceImpl;
|
||||
import org.dspace.discovery.SolrServiceIndexPlugin;
|
||||
import org.dspace.sort.OrderFormat;
|
||||
import org.dspace.sort.SortException;
|
||||
import org.dspace.sort.SortOption;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Andrea Bollini (CILEA)
|
||||
*
|
||||
*/
|
||||
public class SolrBrowseCreateDAO implements BrowseCreateDAO,
|
||||
SolrServiceIndexPlugin
|
||||
{
|
||||
private static final String INFO_NOSQL_TO_RUN = "No SQL to run: data are stored in the SOLR Search Core. PLEASE NOTE THAT YOU MUST UPDATE THE DISCOVERY INDEX AFTER ANY CHANGES TO THE BROWSE CONFIGURATION";
|
||||
|
||||
// reference to a DBMS BrowseCreateDAO needed to remove old tables when
|
||||
// switching from DBMS to SOLR
|
||||
private BrowseCreateDAO dbCreateDAO;
|
||||
|
||||
private static final Logger log = Logger
|
||||
.getLogger(SolrBrowseCreateDAO.class);
|
||||
|
||||
private BrowseIndex[] bis;
|
||||
|
||||
public SolrBrowseCreateDAO()
|
||||
{
|
||||
try
|
||||
{
|
||||
bis = BrowseIndex.getBrowseIndices();
|
||||
}
|
||||
catch (BrowseException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
for (BrowseIndex bi : bis)
|
||||
bi.generateMdBits();
|
||||
}
|
||||
|
||||
public SolrBrowseCreateDAO(Context context) throws BrowseException
|
||||
{
|
||||
// For compatibility with previous versions
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
if ("postgres".equals(db))
|
||||
{
|
||||
dbCreateDAO = new BrowseCreateDAOPostgres(context);
|
||||
}
|
||||
else if ("oracle".equals(db))
|
||||
{
|
||||
dbCreateDAO = new BrowseCreateDAOOracle(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BrowseException(
|
||||
"The configuration for db.name is either invalid, or contains an unrecognised database");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
bis = BrowseIndex.getBrowseIndices();
|
||||
}
|
||||
catch (BrowseException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
for (BrowseIndex bi : bis)
|
||||
bi.generateMdBits();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void additionalIndex(Context context, DSpaceObject dso, SolrInputDocument doc)
|
||||
{
|
||||
if (!(dso instanceof Item))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Item item = (Item) dso;
|
||||
|
||||
// faceting for metadata browsing. It is different than search facet
|
||||
// because if there are authority with variants support we wan't all the
|
||||
// variants to go in the facet... they are sorted by count so just the
|
||||
// prefered label is relevant
|
||||
for (BrowseIndex bi : bis)
|
||||
{
|
||||
log.debug("Indexing for item " + item.getID() + ", for index: "
|
||||
+ bi.getTableName());
|
||||
|
||||
if (bi.isMetadataIndex())
|
||||
{
|
||||
// values to show in the browse list
|
||||
Set<String> distFValues = new HashSet<String>();
|
||||
// value for lookup without authority
|
||||
Set<String> distFVal = new HashSet<String>();
|
||||
// value for lookup with authority
|
||||
Set<String> distFAuths = new HashSet<String>();
|
||||
// value for lookup when partial search (the item mapper tool use it)
|
||||
Set<String> distValuesForAC = new HashSet<String>();
|
||||
|
||||
// now index the new details - but only if it's archived and not
|
||||
// withdrawn
|
||||
if (item.isArchived() || item.isWithdrawn())
|
||||
{
|
||||
// get the metadata from the item
|
||||
for (int mdIdx = 0; mdIdx < bi.getMetadataCount(); mdIdx++)
|
||||
{
|
||||
String[] md = bi.getMdBits(mdIdx);
|
||||
DCValue[] values = item.getMetadata(md[0], md[1],
|
||||
md[2], Item.ANY);
|
||||
|
||||
// if we have values to index on, then do so
|
||||
if (values != null && values.length > 0)
|
||||
{
|
||||
int minConfidence = MetadataAuthorityManager
|
||||
.getManager().getMinConfidence(
|
||||
values[0].schema,
|
||||
values[0].element,
|
||||
values[0].qualifier);
|
||||
|
||||
boolean ignoreAuthority = new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.browse.authority.ignore."
|
||||
+ bi.getName(),
|
||||
new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.browse.authority.ignore",
|
||||
new Boolean(false)),
|
||||
true);
|
||||
for (int x = 0; x < values.length; x++)
|
||||
{
|
||||
// Ensure that there is a value to index before
|
||||
// inserting it
|
||||
if (StringUtils.isEmpty(values[x].value))
|
||||
{
|
||||
log.error("Null metadata value for item "
|
||||
+ item.getID()
|
||||
+ ", field: "
|
||||
+ values[x].schema
|
||||
+ "."
|
||||
+ values[x].element
|
||||
+ (values[x].qualifier == null ? ""
|
||||
: "." + values[x].qualifier));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bi.isAuthorityIndex()
|
||||
&& (values[x].authority == null || values[x].confidence < minConfidence))
|
||||
{
|
||||
// if we have an authority index only
|
||||
// authored metadata will go here!
|
||||
log.debug("Skipping item="
|
||||
+ item.getID() + ", field="
|
||||
+ values[x].schema + "."
|
||||
+ values[x].element + "."
|
||||
+ values[x].qualifier
|
||||
+ ", value=" + values[x].value
|
||||
+ ", authority="
|
||||
+ values[x].authority
|
||||
+ ", confidence="
|
||||
+ values[x].confidence
|
||||
+ " (BAD AUTHORITY)");
|
||||
continue;
|
||||
}
|
||||
|
||||
// is there any valid (with appropriate
|
||||
// confidence) authority key?
|
||||
if ((ignoreAuthority && !bi.isAuthorityIndex())
|
||||
|| (values[x].authority != null && values[x].confidence >= minConfidence))
|
||||
{
|
||||
distFAuths.add(values[x].authority);
|
||||
distValuesForAC.add(values[x].value);
|
||||
|
||||
String preferedLabel = null;
|
||||
boolean ignorePrefered = new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.browse.authority.ignore-prefered."
|
||||
+ bi.getName(),
|
||||
new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.browse.authority.ignore-prefered",
|
||||
new Boolean(
|
||||
false)),
|
||||
true);
|
||||
if (!ignorePrefered)
|
||||
{
|
||||
preferedLabel = ChoiceAuthorityManager
|
||||
.getManager()
|
||||
.getLabel(
|
||||
values[x].schema,
|
||||
values[x].element,
|
||||
values[x].qualifier,
|
||||
values[x].authority,
|
||||
values[x].language);
|
||||
}
|
||||
List<String> variants = null;
|
||||
|
||||
boolean ignoreVariants = new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.browse.authority.ignore-variants."
|
||||
+ bi.getName(),
|
||||
new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.browse.authority.ignore-variants",
|
||||
new Boolean(
|
||||
false)),
|
||||
true);
|
||||
if (!ignoreVariants)
|
||||
{
|
||||
variants = ChoiceAuthorityManager
|
||||
.getManager()
|
||||
.getVariants(
|
||||
values[x].schema,
|
||||
values[x].element,
|
||||
values[x].qualifier,
|
||||
values[x].authority,
|
||||
values[x].language);
|
||||
}
|
||||
|
||||
if (StringUtils
|
||||
.isNotBlank(preferedLabel))
|
||||
{
|
||||
String nLabel = OrderFormat
|
||||
.makeSortString(
|
||||
preferedLabel,
|
||||
values[x].language,
|
||||
bi.getDataType());
|
||||
distFValues
|
||||
.add(nLabel
|
||||
+ SolrServiceImpl.FILTER_SEPARATOR
|
||||
+ preferedLabel
|
||||
+ SolrServiceImpl.AUTHORITY_SEPARATOR
|
||||
+ values[x].authority);
|
||||
distValuesForAC.add(preferedLabel);
|
||||
}
|
||||
|
||||
if (variants != null)
|
||||
{
|
||||
for (String var : variants)
|
||||
{
|
||||
String nVal = OrderFormat
|
||||
.makeSortString(
|
||||
var,
|
||||
values[x].language,
|
||||
bi.getDataType());
|
||||
distFValues
|
||||
.add(nVal
|
||||
+ SolrServiceImpl.FILTER_SEPARATOR
|
||||
+ var
|
||||
+ SolrServiceImpl.AUTHORITY_SEPARATOR
|
||||
+ values[x].authority);
|
||||
distValuesForAC.add(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// put it in the browse index as if it
|
||||
// hasn't have an authority key
|
||||
{
|
||||
// get the normalised version of the
|
||||
// value
|
||||
String nVal = OrderFormat
|
||||
.makeSortString(
|
||||
values[x].value,
|
||||
values[x].language,
|
||||
bi.getDataType());
|
||||
distFValues
|
||||
.add(nVal
|
||||
+ SolrServiceImpl.FILTER_SEPARATOR
|
||||
+ values[x].value);
|
||||
distFVal.add(values[x].value);
|
||||
distValuesForAC.add(values[x].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String facet : distFValues)
|
||||
{
|
||||
doc.addField(bi.getDistinctTableName() + "_filter", facet);
|
||||
}
|
||||
for (String facet : distFAuths)
|
||||
{
|
||||
doc.addField(bi.getDistinctTableName()
|
||||
+ "_authority_filter", facet);
|
||||
}
|
||||
for (String facet : distValuesForAC)
|
||||
{
|
||||
doc.addField(bi.getDistinctTableName() + "_partial", facet);
|
||||
}
|
||||
for (String facet : distFVal)
|
||||
{
|
||||
doc.addField(bi.getDistinctTableName()+"_value_filter", facet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add sorting options as configurated for the browse system
|
||||
try
|
||||
{
|
||||
for (SortOption so : SortOption.getSortOptions())
|
||||
{
|
||||
DCValue[] dcvalue = item.getMetadata(so.getMetadata());
|
||||
if (dcvalue != null && dcvalue.length > 0)
|
||||
{
|
||||
String nValue = OrderFormat
|
||||
.makeSortString(dcvalue[0].value,
|
||||
dcvalue[0].language, so.getType());
|
||||
doc.addField("bi_sort_" + so.getNumber() + "_sort", nValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SortException e)
|
||||
{
|
||||
// we can't solve it so rethrow as runtime exception
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByItemID(String table, int itemID) throws BrowseException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCommunityMappings(int itemID) throws BrowseException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCommunityMappings(int itemID) throws BrowseException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertIndex(String table, int itemID, Map sortCols)
|
||||
throws BrowseException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateIndex(String table, int itemID, Map sortCols)
|
||||
throws BrowseException
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistinctID(String table, String value, String authority,
|
||||
String sortValue) throws BrowseException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertDistinctRecord(String table, String value,
|
||||
String authority, String sortValue) throws BrowseException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropIndexAndRelated(String table, boolean execute)
|
||||
throws BrowseException
|
||||
{
|
||||
return dbCreateDAO.dropIndexAndRelated(table, execute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropSequence(String sequence, boolean execute)
|
||||
throws BrowseException
|
||||
{
|
||||
return dbCreateDAO.dropSequence(sequence, execute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropView(String view, boolean execute) throws BrowseException
|
||||
{
|
||||
return dbCreateDAO.dropView(view, execute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createSequence(String sequence, boolean execute)
|
||||
throws BrowseException
|
||||
{
|
||||
return INFO_NOSQL_TO_RUN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createPrimaryTable(String table, List sortCols,
|
||||
boolean execute) throws BrowseException
|
||||
{
|
||||
return INFO_NOSQL_TO_RUN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] createDatabaseIndices(String table, List<Integer> sortCols,
|
||||
boolean value, boolean execute) throws BrowseException
|
||||
{
|
||||
return new String[] { INFO_NOSQL_TO_RUN };
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] createMapIndices(String disTable, String mapTable,
|
||||
boolean execute) throws BrowseException
|
||||
{
|
||||
return new String[] { INFO_NOSQL_TO_RUN };
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createCollectionView(String table, String view,
|
||||
boolean execute) throws BrowseException
|
||||
{
|
||||
return INFO_NOSQL_TO_RUN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createCommunityView(String table, String view, boolean execute)
|
||||
throws BrowseException
|
||||
{
|
||||
return INFO_NOSQL_TO_RUN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createDistinctTable(String table, boolean execute)
|
||||
throws BrowseException
|
||||
{
|
||||
return INFO_NOSQL_TO_RUN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createDistinctMap(String table, String map, boolean execute)
|
||||
throws BrowseException
|
||||
{
|
||||
return INFO_NOSQL_TO_RUN;
|
||||
}
|
||||
|
||||
public MappingResults updateDistinctMappings(String table, int itemID,
|
||||
Set<Integer> distinctIDs) throws BrowseException
|
||||
{
|
||||
return new MappingResults()
|
||||
{
|
||||
|
||||
@Override
|
||||
public List<Integer> getRetainedDistinctIds()
|
||||
{
|
||||
return new ArrayList<Integer>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getRemovedDistinctIds()
|
||||
{
|
||||
return new ArrayList<Integer>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getAddedDistinctIds()
|
||||
{
|
||||
return new ArrayList<Integer>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testTableExistence(String table) throws BrowseException
|
||||
{
|
||||
return dbCreateDAO.testTableExistence(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> deleteMappingsByItemID(String mapTable, int itemID)
|
||||
throws BrowseException
|
||||
{
|
||||
return new ArrayList<Integer>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pruneExcess(String table, boolean withdrawn)
|
||||
throws BrowseException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pruneMapExcess(String map, boolean withdrawn,
|
||||
List<Integer> distinctIds) throws BrowseException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pruneDistinct(String table, String map,
|
||||
List<Integer> distinctIds) throws BrowseException
|
||||
{
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,741 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.browse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.DiscoverFacetField;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
import org.dspace.discovery.DiscoverQuery.SORT_ORDER;
|
||||
import org.dspace.discovery.DiscoverResult;
|
||||
import org.dspace.discovery.DiscoverResult.FacetResult;
|
||||
import org.dspace.discovery.DiscoverResult.SearchDocument;
|
||||
import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Andrea Bollini (CILEA)
|
||||
*
|
||||
*/
|
||||
public class SolrBrowseDAO implements BrowseDAO
|
||||
{
|
||||
public SolrBrowseDAO(Context context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
static private class FacetValueComparator implements Comparator
|
||||
{
|
||||
@Override
|
||||
public int compare(Object o1, Object o2)
|
||||
{
|
||||
String s1 = "", s2 = "";
|
||||
if (o1 instanceof FacetResult && o2 instanceof String)
|
||||
{
|
||||
FacetResult c = (FacetResult) o1;
|
||||
s1 = c.getSortValue();
|
||||
s2 = (String) o2;
|
||||
}
|
||||
else if (o2 instanceof FacetResult && o1 instanceof String)
|
||||
{
|
||||
FacetResult c = (FacetResult) o2;
|
||||
s1 = (String) o1;
|
||||
s2 = c.getSortValue();
|
||||
}
|
||||
// both object are FacetResult so they are already sorted
|
||||
return s1.compareTo(s2);
|
||||
}
|
||||
}
|
||||
|
||||
/** Log4j log */
|
||||
private static Logger log = Logger.getLogger(SolrBrowseDAO.class);
|
||||
|
||||
/** The DSpace context */
|
||||
private Context context;
|
||||
|
||||
// SQL query related attributes for this class
|
||||
|
||||
/** table(s) to select from */
|
||||
private String table = null;
|
||||
|
||||
/** field to look for focus value in */
|
||||
private String focusField = null;
|
||||
|
||||
/** value to start browse from in focus field */
|
||||
private String focusValue = null;
|
||||
|
||||
/** field to look for value in */
|
||||
private String valueField = null;
|
||||
|
||||
/** value to restrict browse to (e.g. author name) */
|
||||
private String value = null;
|
||||
|
||||
private String authority = null;
|
||||
|
||||
/** exact or partial matching of the value */
|
||||
private boolean valuePartial = false;
|
||||
|
||||
/** the table that defines the mapping for the relevant container */
|
||||
private String containerTable = null;
|
||||
|
||||
/**
|
||||
* the name of the field which contains the container id (e.g.
|
||||
* collection_id)
|
||||
*/
|
||||
private String containerIDField = null;
|
||||
|
||||
/** the database id of the container we are constraining to */
|
||||
private int containerID = -1;
|
||||
|
||||
/** the column that we are sorting results by */
|
||||
private String orderField = null;
|
||||
|
||||
/** whether to sort results ascending or descending */
|
||||
private boolean ascending = true;
|
||||
|
||||
/** the limit of number of results to return */
|
||||
private int limit = -1;
|
||||
|
||||
/** the offset of the start point */
|
||||
private int offset = 0;
|
||||
|
||||
/** whether to use the equals comparator in value comparisons */
|
||||
private boolean equalsComparator = true;
|
||||
|
||||
/** whether this is a distinct browse or not */
|
||||
private boolean distinct = false;
|
||||
|
||||
private String facetField;
|
||||
|
||||
// administrative attributes for this class
|
||||
|
||||
DSpace dspace = new DSpace();
|
||||
|
||||
SearchService searcher = dspace.getServiceManager().getServiceByName(
|
||||
SearchService.class.getName(), SearchService.class);
|
||||
|
||||
private DiscoverResult sResponse = null;
|
||||
|
||||
private boolean itemsWithdrawn = false;
|
||||
private boolean itemsPrivate = false;
|
||||
|
||||
private DiscoverResult getSolrResponse() throws BrowseException
|
||||
{
|
||||
if (sResponse == null)
|
||||
{
|
||||
DiscoverQuery query = new DiscoverQuery();
|
||||
addLocationScopeFilter(query);
|
||||
addStatusFilter(query);
|
||||
if (distinct)
|
||||
{
|
||||
DiscoverFacetField dff = new DiscoverFacetField(facetField,
|
||||
DiscoveryConfigurationParameters.TYPE_TEXT, -1,
|
||||
DiscoveryConfigurationParameters.SORT.VALUE);
|
||||
query.addFacetField(dff);
|
||||
query.setFacetMinCount(1);
|
||||
query.setMaxResults(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
query.setMaxResults(limit > 0 ? limit : 20);
|
||||
if (offset > 0)
|
||||
{
|
||||
query.setStart(offset);
|
||||
}
|
||||
|
||||
// caution check first authority, value is always present!
|
||||
if (authority != null)
|
||||
{
|
||||
query.addFilterQueries("{!field f="+facetField + "_authority_filter}"
|
||||
+ authority);
|
||||
}
|
||||
else if (value != null && !valuePartial)
|
||||
{
|
||||
query.addFilterQueries("{!field f="+facetField + "_value_filter}" + value);
|
||||
}
|
||||
else if (valuePartial)
|
||||
{
|
||||
query.addFilterQueries("{!field f="+facetField + "_partial}" + value);
|
||||
}
|
||||
// filter on item to be sure to don't include any other object
|
||||
// indexed in the Discovery Search core
|
||||
query.addFilterQueries("search.resourcetype:" + Constants.ITEM);
|
||||
if (orderField != null)
|
||||
{
|
||||
query.setSortField("bi_" + orderField + "_sort",
|
||||
ascending ? SORT_ORDER.asc : SORT_ORDER.desc);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
sResponse = searcher.search(context, query, itemsWithdrawn);
|
||||
}
|
||||
catch (SearchServiceException e)
|
||||
{
|
||||
throw new BrowseException(e);
|
||||
}
|
||||
}
|
||||
return sResponse;
|
||||
}
|
||||
|
||||
private void addStatusFilter(DiscoverQuery query)
|
||||
{
|
||||
if (itemsWithdrawn)
|
||||
{
|
||||
query.addFilterQueries("withdrawn:true");
|
||||
if (itemsPrivate)
|
||||
{
|
||||
query.addFilterQueries("discoverable:false");
|
||||
}
|
||||
else
|
||||
{
|
||||
query.addFilterQueries("NOT(discoverable:false)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
query.addFilterQueries("NOT(withdrawn:true)");
|
||||
}
|
||||
}
|
||||
|
||||
private void addLocationScopeFilter(DiscoverQuery query)
|
||||
{
|
||||
if (containerID > 0)
|
||||
{
|
||||
if (containerIDField.startsWith("collection"))
|
||||
{
|
||||
query.addFilterQueries("location.coll:" + containerID);
|
||||
}
|
||||
else if (containerIDField.startsWith("community"))
|
||||
{
|
||||
query.addFilterQueries("location.comm:" + containerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int doCountQuery() throws BrowseException
|
||||
{
|
||||
DiscoverResult resp = getSolrResponse();
|
||||
int count = 0;
|
||||
if (distinct)
|
||||
{
|
||||
List<FacetResult> facetResults = resp.getFacetResult(facetField);
|
||||
count = facetResults.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need to cast to int to respect the BrowseDAO contract...
|
||||
count = (int) resp.getTotalSearchResults();
|
||||
// FIXME null the response cache
|
||||
// the BrowseEngine send fake argument to the BrowseDAO for the
|
||||
// count...
|
||||
sResponse = null;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List doValueQuery() throws BrowseException
|
||||
{
|
||||
DiscoverResult resp = getSolrResponse();
|
||||
List<FacetResult> facet = resp.getFacetResult(facetField);
|
||||
int count = doCountQuery();
|
||||
int start = offset > 0 ? offset : 0;
|
||||
int max = limit > 0 ? limit : 20;
|
||||
List<String[]> result = new ArrayList<String[]>();
|
||||
if (ascending)
|
||||
{
|
||||
for (int i = start; i < (start + max) && i < count; i++)
|
||||
{
|
||||
FacetResult c = facet.get(i);
|
||||
result.add(new String[] { c.getDisplayedValue(),
|
||||
c.getAuthorityKey() });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = count - start - 1; i >= count - (start + max)
|
||||
&& i >= 0; i--)
|
||||
{
|
||||
FacetResult c = facet.get(i);
|
||||
result.add(new String[] { c.getDisplayedValue(),
|
||||
c.getAuthorityKey() });
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List doQuery() throws BrowseException
|
||||
{
|
||||
DiscoverResult resp = getSolrResponse();
|
||||
|
||||
List<BrowseItem> bitems = new ArrayList<BrowseItem>();
|
||||
for (DSpaceObject solrDoc : resp.getDspaceObjects())
|
||||
{
|
||||
// FIXME introduce project, don't retrieve Item immediately when
|
||||
// processing the query...
|
||||
Item item = (Item) solrDoc;
|
||||
BrowseItem bitem = new BrowseItem(context, item.getID(),
|
||||
item.isArchived(), item.isWithdrawn());
|
||||
bitems.add(bitem);
|
||||
}
|
||||
return bitems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doMaxQuery(String column, String table, int itemID)
|
||||
throws BrowseException
|
||||
{
|
||||
DiscoverQuery query = new DiscoverQuery();
|
||||
query.setQuery("search.resourceid:" + itemID
|
||||
+ " AND search.resourcetype:" + Constants.ITEM);
|
||||
query.setMaxResults(1);
|
||||
DiscoverResult resp = null;
|
||||
try
|
||||
{
|
||||
resp = searcher.search(context, query);
|
||||
}
|
||||
catch (SearchServiceException e)
|
||||
{
|
||||
throw new BrowseException(e);
|
||||
}
|
||||
if (resp.getTotalSearchResults() > 0)
|
||||
{
|
||||
SearchDocument doc = resp.getSearchDocument(
|
||||
resp.getDspaceObjects().get(0)).get(0);
|
||||
return (String) doc.getSearchFieldValues(column).get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int doOffsetQuery(String column, String value, boolean isAscending)
|
||||
throws BrowseException
|
||||
{
|
||||
DiscoverQuery query = new DiscoverQuery();
|
||||
addLocationScopeFilter(query);
|
||||
addStatusFilter(query);
|
||||
query.setMaxResults(0);
|
||||
query.addFilterQueries("search.resourcetype:" + Constants.ITEM);
|
||||
if (isAscending)
|
||||
{
|
||||
query.setQuery("bi_"+column + "_sort" + ": [* TO \"" + value + "\"]");
|
||||
}
|
||||
else
|
||||
{
|
||||
query.setQuery("bi_" + column + "_sort" + ": [\"" + value + "\" TO *]");
|
||||
}
|
||||
DiscoverResult resp = null;
|
||||
try
|
||||
{
|
||||
resp = searcher.search(context, query);
|
||||
}
|
||||
catch (SearchServiceException e)
|
||||
{
|
||||
throw new BrowseException(e);
|
||||
}
|
||||
return (int) resp.getTotalSearchResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int doDistinctOffsetQuery(String column, String value,
|
||||
boolean isAscending) throws BrowseException
|
||||
{
|
||||
DiscoverResult resp = getSolrResponse();
|
||||
List<FacetResult> facets = resp.getFacetResult(facetField);
|
||||
Comparator comparator = new SolrBrowseDAO.FacetValueComparator();
|
||||
Collections.sort(facets, comparator);
|
||||
int x = Collections.binarySearch(facets, value, comparator);
|
||||
int ascValue = (x >= 0) ? x : -(x + 1);
|
||||
if (isAscending)
|
||||
{
|
||||
return ascValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return doCountQuery() - ascValue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getContainerID()
|
||||
*/
|
||||
public int getContainerID()
|
||||
{
|
||||
return containerID;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getContainerIDField()
|
||||
*/
|
||||
public String getContainerIDField()
|
||||
{
|
||||
return containerIDField;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getContainerTable()
|
||||
*/
|
||||
public String getContainerTable()
|
||||
{
|
||||
return containerTable;
|
||||
}
|
||||
|
||||
// FIXME is this in use?
|
||||
public String[] getCountValues()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getFocusField()
|
||||
*/
|
||||
public String getJumpToField()
|
||||
{
|
||||
return focusField;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getFocusValue()
|
||||
*/
|
||||
public String getJumpToValue()
|
||||
{
|
||||
return focusValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getLimit()
|
||||
*/
|
||||
public int getLimit()
|
||||
{
|
||||
return limit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getOffset()
|
||||
*/
|
||||
public int getOffset()
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getOrderField()
|
||||
*/
|
||||
public String getOrderField()
|
||||
{
|
||||
return orderField;
|
||||
}
|
||||
|
||||
// is this in use?
|
||||
public String[] getSelectValues()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getTable()
|
||||
*/
|
||||
public String getTable()
|
||||
{
|
||||
return table;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getValue()
|
||||
*/
|
||||
public String getFilterValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#getValueField()
|
||||
*/
|
||||
public String getFilterValueField()
|
||||
{
|
||||
return valueField;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#isAscending()
|
||||
*/
|
||||
public boolean isAscending()
|
||||
{
|
||||
return ascending;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#isDistinct()
|
||||
*/
|
||||
public boolean isDistinct()
|
||||
{
|
||||
return this.distinct;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setAscending(boolean)
|
||||
*/
|
||||
public void setAscending(boolean ascending)
|
||||
{
|
||||
this.ascending = ascending;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setContainerID(int)
|
||||
*/
|
||||
public void setContainerID(int containerID)
|
||||
{
|
||||
this.containerID = containerID;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setContainerIDField(java.lang.String)
|
||||
*/
|
||||
public void setContainerIDField(String containerIDField)
|
||||
{
|
||||
this.containerIDField = containerIDField;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setContainerTable(java.lang.String)
|
||||
*/
|
||||
public void setContainerTable(String containerTable)
|
||||
{
|
||||
this.containerTable = containerTable;
|
||||
|
||||
}
|
||||
|
||||
// is this in use?
|
||||
public void setCountValues(String[] fields)
|
||||
{
|
||||
// this.countValues = fields;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setDistinct(boolean)
|
||||
*/
|
||||
public void setDistinct(boolean bool)
|
||||
{
|
||||
this.distinct = bool;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setEqualsComparator(boolean)
|
||||
*/
|
||||
public void setEqualsComparator(boolean equalsComparator)
|
||||
{
|
||||
this.equalsComparator = equalsComparator;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setFocusField(java.lang.String)
|
||||
*/
|
||||
public void setJumpToField(String focusField)
|
||||
{
|
||||
this.focusField = focusField;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setFocusValue(java.lang.String)
|
||||
*/
|
||||
public void setJumpToValue(String focusValue)
|
||||
{
|
||||
this.focusValue = focusValue;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setLimit(int)
|
||||
*/
|
||||
public void setLimit(int limit)
|
||||
{
|
||||
this.limit = limit;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setOffset(int)
|
||||
*/
|
||||
public void setOffset(int offset)
|
||||
{
|
||||
this.offset = offset;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setOrderField(java.lang.String)
|
||||
*/
|
||||
public void setOrderField(String orderField)
|
||||
{
|
||||
this.orderField = orderField;
|
||||
|
||||
}
|
||||
|
||||
// is this in use?
|
||||
public void setSelectValues(String[] selectValues)
|
||||
{
|
||||
// this.selectValues = selectValues;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setTable(java.lang.String)
|
||||
*/
|
||||
public void setTable(String table)
|
||||
{
|
||||
if (table.equals(BrowseIndex.getWithdrawnBrowseIndex().getTableName()))
|
||||
{
|
||||
itemsWithdrawn = true;
|
||||
itemsPrivate = false;
|
||||
}
|
||||
else if (table.equals(BrowseIndex.getPrivateBrowseIndex().getTableName()))
|
||||
{
|
||||
itemsPrivate = true;
|
||||
// items private are also withdrawn
|
||||
itemsWithdrawn = true;
|
||||
}
|
||||
facetField = table;
|
||||
}
|
||||
|
||||
public void setFilterMappingTables(String tableDis, String tableMap)
|
||||
{
|
||||
if (tableDis != null)
|
||||
{
|
||||
this.facetField = tableDis;
|
||||
}
|
||||
// this.fields = tableDis;
|
||||
// this.tableMap = tableMap;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setValue(java.lang.String)
|
||||
*/
|
||||
public void setFilterValue(String value)
|
||||
{
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setFilterValuePartial(boolean)
|
||||
*/
|
||||
public void setFilterValuePartial(boolean part)
|
||||
{
|
||||
this.valuePartial = part;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#setValueField(java.lang.String)
|
||||
*/
|
||||
public void setFilterValueField(String valueField)
|
||||
{
|
||||
this.valueField = valueField;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.dspace.browse.BrowseDAO#useEqualsComparator()
|
||||
*/
|
||||
public boolean useEqualsComparator()
|
||||
{
|
||||
return equalsComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorityValue()
|
||||
{
|
||||
return authority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthorityValue(String value)
|
||||
{
|
||||
this.authority = value;
|
||||
}
|
||||
}
|
@@ -33,6 +33,9 @@ import org.apache.solr.common.params.MoreLikeThisParams;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.dspace.content.*;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.authority.ChoiceAuthorityManager;
|
||||
import org.dspace.content.authority.Choices;
|
||||
import org.dspace.content.authority.MetadataAuthorityManager;
|
||||
import org.dspace.core.*;
|
||||
import org.dspace.discovery.configuration.*;
|
||||
import org.dspace.handle.HandleManager;
|
||||
@@ -74,6 +77,12 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
|
||||
public static final String FILTER_SEPARATOR = "\n|||\n";
|
||||
|
||||
public static final String AUTHORITY_SEPARATOR = "\n§§§\n";
|
||||
|
||||
public static final String STORE_SEPARATOR = "\n|||\n";
|
||||
|
||||
public static final String VARIANTS_STORE_SEPARATOR = "\n§§§\n";
|
||||
|
||||
/**
|
||||
* Non-Static CommonsHttpSolrServer for processing indexing events.
|
||||
*/
|
||||
@@ -141,7 +150,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
{
|
||||
case Constants.ITEM:
|
||||
Item item = (Item) dso;
|
||||
if (item.isArchived() && !item.isWithdrawn())
|
||||
if (item.isArchived() || item.isWithdrawn())
|
||||
{
|
||||
/**
|
||||
* If the item is in the repository now, add it to the index
|
||||
@@ -155,9 +164,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
} else {
|
||||
/**
|
||||
* Make sure the item is not in the index if it is not in
|
||||
* archive. TODO: Someday DSIndexer should block withdrawn
|
||||
* content on search/retrieval and allow admins the ability
|
||||
* to still search for withdrawn Items.
|
||||
* archive or withwrawn.
|
||||
*/
|
||||
unIndexContent(context, handle);
|
||||
log.info("Removed Item: " + handle + " from Index");
|
||||
@@ -721,9 +728,12 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
|
||||
SolrInputDocument doc = buildDocument(Constants.ITEM, item.getID(), handle,
|
||||
locations);
|
||||
|
||||
|
||||
log.debug("Building Item: " + handle);
|
||||
|
||||
doc.addField("withdrawn", item.isWithdrawn());
|
||||
doc.addField("discoverable", item.isDiscoverable());
|
||||
|
||||
//Keep a list of our sort values which we added, sort values can only be added once
|
||||
List<String> sortFieldsAdded = new ArrayList<String>();
|
||||
Set<String> hitHighlightingFields = new HashSet<String>();
|
||||
@@ -780,7 +790,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
{
|
||||
hitHighlightingFields.add(fieldConfiguration.getField());
|
||||
}
|
||||
}
|
||||
}
|
||||
DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration = discoveryConfiguration.getMoreLikeThisConfiguration();
|
||||
if(moreLikeThisConfiguration != null)
|
||||
{
|
||||
@@ -805,6 +815,19 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
toIgnoreFields.add(ignoreFieldsString);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> toProjectionFields = new ArrayList<String>();
|
||||
String projectionFieldsString = new DSpace().getConfigurationService().getProperty("discovery.index.projection");
|
||||
if(projectionFieldsString != null){
|
||||
if(projectionFieldsString.indexOf(",") != -1){
|
||||
for (int i = 0; i < projectionFieldsString.split(",").length; i++) {
|
||||
toProjectionFields.add(projectionFieldsString.split(",")[i].trim());
|
||||
}
|
||||
} else {
|
||||
toProjectionFields.add(projectionFieldsString);
|
||||
}
|
||||
}
|
||||
|
||||
DCValue[] mydc = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||
for (DCValue meta : mydc)
|
||||
{
|
||||
@@ -813,7 +836,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
|
||||
String value = meta.value;
|
||||
|
||||
if (value == null)
|
||||
if (value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -823,12 +846,83 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
field += "." + meta.qualifier;
|
||||
}
|
||||
|
||||
|
||||
//We are not indexing provenance, this is useless
|
||||
if (toIgnoreFields.contains(field) || toIgnoreFields.contains(unqualifiedField + "." + Item.ANY))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String authority = null;
|
||||
String preferedLabel = null;
|
||||
List<String> variants = null;
|
||||
boolean isAuthorityControlled = MetadataAuthorityManager
|
||||
.getManager().isAuthorityControlled(meta.schema,
|
||||
meta.element,
|
||||
meta.qualifier);
|
||||
|
||||
int minConfidence = isAuthorityControlled?MetadataAuthorityManager
|
||||
.getManager().getMinConfidence(
|
||||
meta.schema,
|
||||
meta.element,
|
||||
meta.qualifier):Choices.CF_ACCEPTED;
|
||||
|
||||
if (isAuthorityControlled && meta.authority != null
|
||||
&& meta.confidence >= minConfidence)
|
||||
{
|
||||
boolean ignoreAuthority = new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.index.authority.ignore." + field,
|
||||
new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.index.authority.ignore",
|
||||
new Boolean(false)), true);
|
||||
if (!ignoreAuthority)
|
||||
{
|
||||
authority = meta.authority;
|
||||
|
||||
boolean ignorePrefered = new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.index.authority.ignore-prefered."
|
||||
+ field,
|
||||
new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.index.authority.ignore-prefered",
|
||||
new Boolean(false)),
|
||||
true);
|
||||
if (!ignorePrefered)
|
||||
{
|
||||
|
||||
preferedLabel = ChoiceAuthorityManager.getManager()
|
||||
.getLabel(meta.schema, meta.element,
|
||||
meta.qualifier, meta.authority,
|
||||
meta.language);
|
||||
}
|
||||
|
||||
boolean ignoreVariants = new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.index.authority.ignore-variants."
|
||||
+ field,
|
||||
new DSpace()
|
||||
.getConfigurationService()
|
||||
.getPropertyAsType(
|
||||
"discovery.index.authority.ignore-variants",
|
||||
new Boolean(false)),
|
||||
true);
|
||||
if (!ignoreVariants)
|
||||
{
|
||||
variants = ChoiceAuthorityManager.getManager()
|
||||
.getVariants(meta.schema, meta.element,
|
||||
meta.qualifier, meta.authority,
|
||||
meta.language);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((searchFilters.get(field) != null || searchFilters.get(unqualifiedField + "." + Item.ANY) != null))
|
||||
{
|
||||
@@ -851,37 +945,70 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
value = DateFormatUtils.formatUTC(date, "yyyy-MM-dd");
|
||||
}
|
||||
}
|
||||
|
||||
doc.addField(searchFilter.getIndexFieldName(), value);
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_keyword", value);
|
||||
|
||||
if (preferedLabel != null)
|
||||
{
|
||||
doc.addField(searchFilter.getIndexFieldName(), preferedLabel);
|
||||
}
|
||||
if (variants != null)
|
||||
{
|
||||
for (String var : variants)
|
||||
{
|
||||
doc.addField(searchFilter.getIndexFieldName(), var);
|
||||
}
|
||||
}
|
||||
|
||||
//Add a dynamic fields for auto complete in search
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_keyword", value);
|
||||
if (preferedLabel != null)
|
||||
{
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_keyword", preferedLabel);
|
||||
}
|
||||
if (variants != null)
|
||||
{
|
||||
for (String var : variants)
|
||||
{
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_ac", var);
|
||||
}
|
||||
}
|
||||
|
||||
if(searchFilter.getFilterType().equals(DiscoverySearchFilterFacet.FILTER_TYPE_FACET))
|
||||
{
|
||||
if(searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_TEXT))
|
||||
{
|
||||
//Add a special filter
|
||||
//We use a separator to split up the lowercase and regular case, this is needed to get our filters in regular case
|
||||
//Solr has issues with facet prefix and cases
|
||||
String separator = new DSpace().getConfigurationService().getProperty("discovery.solr.facets.split.char");
|
||||
//Add a special filter
|
||||
//We use a separator to split up the lowercase and regular case, this is needed to get our filters in regular case
|
||||
//Solr has issues with facet prefix and cases
|
||||
String separator = new DSpace().getConfigurationService().getProperty("discovery.solr.facets.split.char");
|
||||
if(separator == null)
|
||||
{
|
||||
separator = FILTER_SEPARATOR;
|
||||
}
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_filter", value.toLowerCase() + separator + value);
|
||||
separator = FILTER_SEPARATOR;
|
||||
}
|
||||
if (authority != null)
|
||||
{
|
||||
String facetValue = preferedLabel != null?preferedLabel:value;
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_filter", facetValue.toLowerCase() + separator + facetValue + AUTHORITY_SEPARATOR + authority);
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_filter", value.toLowerCase() + separator + value);
|
||||
}
|
||||
}else
|
||||
if(searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE))
|
||||
{
|
||||
if(date != null)
|
||||
if(searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE))
|
||||
{
|
||||
String indexField = searchFilter.getIndexFieldName() + ".year";
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_keyword", DateFormatUtils.formatUTC(date, "yyyy"));
|
||||
doc.addField(indexField, DateFormatUtils.formatUTC(date, "yyyy"));
|
||||
//Also save a sort value of this year, this is required for determining the upper & lower bound year of our facet
|
||||
if(doc.getField(indexField + "_sort") == null)
|
||||
if(date != null)
|
||||
{
|
||||
//We can only add one year so take the first one
|
||||
doc.addField(indexField + "_sort", DateFormatUtils.formatUTC(date, "yyyy"));
|
||||
}
|
||||
String indexField = searchFilter.getIndexFieldName() + ".year";
|
||||
doc.addField(searchFilter.getIndexFieldName() + "_keyword", DateFormatUtils.formatUTC(date, "yyyy"));
|
||||
doc.addField(indexField, DateFormatUtils.formatUTC(date, "yyyy"));
|
||||
//Also save a sort value of this year, this is required for determining the upper & lower bound year of our facet
|
||||
if(doc.getField(indexField + "_sort") == null)
|
||||
{
|
||||
//We can only add one year so take the first one
|
||||
doc.addField(indexField + "_sort", DateFormatUtils.formatUTC(date, "yyyy"));
|
||||
}
|
||||
}
|
||||
}else
|
||||
if(searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_HIERARCHICAL))
|
||||
@@ -961,8 +1088,30 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
doc.addField(field + "_mlt", value);
|
||||
}
|
||||
|
||||
doc.addField(field, value.toLowerCase());
|
||||
|
||||
doc.addField(field, value);
|
||||
if (toProjectionFields.contains(field) || toProjectionFields.contains(unqualifiedField + "." + Item.ANY))
|
||||
{
|
||||
StringBuffer variantsToStore = new StringBuffer();
|
||||
if (variants != null)
|
||||
{
|
||||
for (String var : variants)
|
||||
{
|
||||
variantsToStore.append(VARIANTS_STORE_SEPARATOR);
|
||||
variantsToStore.append(var);
|
||||
}
|
||||
}
|
||||
doc.addField(
|
||||
field + "_stored",
|
||||
value + STORE_SEPARATOR + preferedLabel
|
||||
+ STORE_SEPARATOR
|
||||
+ (variantsToStore.length() > VARIANTS_STORE_SEPARATOR
|
||||
.length() ? variantsToStore
|
||||
.substring(VARIANTS_STORE_SEPARATOR
|
||||
.length()) : "null")
|
||||
+ STORE_SEPARATOR + authority
|
||||
+ STORE_SEPARATOR + meta.language);
|
||||
}
|
||||
|
||||
if (meta.language != null && !meta.language.trim().equals(""))
|
||||
{
|
||||
String langField = field + "." + meta.language;
|
||||
@@ -1212,7 +1361,21 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
}
|
||||
|
||||
//******** SearchService implementation
|
||||
public DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery discoveryQuery) throws SearchServiceException {
|
||||
@Override
|
||||
public DiscoverResult search(Context context, DiscoverQuery query) throws SearchServiceException
|
||||
{
|
||||
return search(context, query, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscoverResult search(Context context, DSpaceObject dso,
|
||||
DiscoverQuery query)
|
||||
throws SearchServiceException
|
||||
{
|
||||
return search(context, dso, query);
|
||||
}
|
||||
|
||||
public DiscoverResult search(Context context, DSpaceObject dso, DiscoverQuery discoveryQuery, boolean includeWithdrawn) throws SearchServiceException {
|
||||
if(dso != null)
|
||||
{
|
||||
if (dso instanceof Community)
|
||||
@@ -1226,14 +1389,14 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
discoveryQuery.addFilterQueries("handle:" + dso.getHandle());
|
||||
}
|
||||
}
|
||||
return search(context, discoveryQuery);
|
||||
return search(context, discoveryQuery, includeWithdrawn);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public DiscoverResult search(Context context, DiscoverQuery discoveryQuery) throws SearchServiceException {
|
||||
public DiscoverResult search(Context context, DiscoverQuery discoveryQuery, boolean includeWithdrawn) throws SearchServiceException {
|
||||
try {
|
||||
SolrQuery solrQuery = resolveToSolrQuery(context, discoveryQuery);
|
||||
SolrQuery solrQuery = resolveToSolrQuery(context, discoveryQuery, includeWithdrawn);
|
||||
|
||||
|
||||
QueryResponse queryResponse = getSolr().query(solrQuery);
|
||||
@@ -1245,17 +1408,22 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
}
|
||||
}
|
||||
|
||||
protected SolrQuery resolveToSolrQuery(Context context, DiscoverQuery discoveryQuery)
|
||||
protected SolrQuery resolveToSolrQuery(Context context, DiscoverQuery discoveryQuery, boolean includeWithdrawn)
|
||||
{
|
||||
SolrQuery solrQuery = new SolrQuery();
|
||||
|
||||
String query = "*:*";
|
||||
if(discoveryQuery.getQuery() != null)
|
||||
{
|
||||
query = discoveryQuery.getQuery();
|
||||
}
|
||||
query = discoveryQuery.getQuery();
|
||||
}
|
||||
|
||||
solrQuery.setQuery(query);
|
||||
|
||||
if (!includeWithdrawn)
|
||||
{
|
||||
solrQuery.addFilterQuery("NOT(withdrawn:true)");
|
||||
}
|
||||
|
||||
for (int i = 0; i < discoveryQuery.getFilterQueries().size(); i++)
|
||||
{
|
||||
@@ -1380,7 +1548,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
|
||||
|
||||
public InputStream searchJSON(Context context, DiscoverQuery discoveryQuery, String jsonIdentifier) throws SearchServiceException {
|
||||
SolrQuery solrQuery = resolveToSolrQuery(context, discoveryQuery);
|
||||
SolrQuery solrQuery = resolveToSolrQuery(context, discoveryQuery, false);
|
||||
//We use json as out output type
|
||||
solrQuery.setParam("json.nl", "map");
|
||||
solrQuery.setParam("json.wrf", jsonIdentifier);
|
||||
@@ -1401,7 +1569,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected DiscoverResult retrieveResult(Context context, DiscoverQuery query, QueryResponse solrQueryResponse) throws SQLException {
|
||||
DiscoverResult result = new DiscoverResult();
|
||||
|
||||
@@ -1476,8 +1644,14 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
{
|
||||
String displayedValue = transformDisplayedValue(context, facetField.getName(), facetValue.getName());
|
||||
String field = transformFacetField(facetFieldConfig, facetField.getName(), true);
|
||||
|
||||
result.addFacetResult(field, new DiscoverResult.FacetResult(displayedValue, displayedValue, facetValue.getCount()));
|
||||
String authorityValue = transformAuthorityValue(context, facetField.getName(), facetValue.getName());
|
||||
String sortValue = transformSortValue(context, facetField.getName(), facetValue.getName());
|
||||
result.addFacetResult(
|
||||
field,
|
||||
new DiscoverResult.FacetResult(facetValue
|
||||
.getAsFilterQuery(),
|
||||
displayedValue, authorityValue,
|
||||
sortValue, facetValue.getCount()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1498,13 +1672,13 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
name = name.substring(0, name.lastIndexOf(']')).replaceAll("TO", "-");
|
||||
String filter = facetQuery.substring(facetQuery.indexOf('['));
|
||||
filter = filter.substring(0, filter.lastIndexOf(']') + 1);
|
||||
|
||||
|
||||
Integer count = sortedFacetQueries.get(facetQuery);
|
||||
|
||||
//No need to show empty years
|
||||
if(0 < count)
|
||||
{
|
||||
result.addFacetResult(facetField, new DiscoverResult.FacetResult(filter, name, count));
|
||||
result.addFacetResult(facetField, new DiscoverResult.FacetResult(filter, name, null, name, count));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1597,7 +1771,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
return new ArrayList<DSpaceObject>(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DiscoverFilterQuery toFilterQuery(Context context, String field, String operator, String value) throws SQLException{
|
||||
DiscoverFilterQuery result = new DiscoverFilterQuery();
|
||||
|
||||
@@ -1689,7 +1863,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toSortFieldIndex(String metadataField, String type)
|
||||
{
|
||||
@@ -1761,6 +1935,68 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
StringBuffer valueBuffer = new StringBuffer();
|
||||
int start = fqParts.length / 2;
|
||||
for(int i = start; i < fqParts.length; i++)
|
||||
{
|
||||
String[] split = fqParts[i].split(AUTHORITY_SEPARATOR, 2);
|
||||
valueBuffer.append(split[0]);
|
||||
}
|
||||
value = valueBuffer.toString();
|
||||
}else if(value.matches("\\((.*?)\\)"))
|
||||
{
|
||||
//The brackets where added for better solr results, remove the first & last one
|
||||
value = value.substring(1, value.length() -1);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected String transformAuthorityValue(Context context, String field, String value) throws SQLException {
|
||||
if(field.endsWith("_filter"))
|
||||
{
|
||||
//We have a filter make sure we split !
|
||||
String separator = new DSpace().getConfigurationService().getProperty("discovery.solr.facets.split.char");
|
||||
if(separator == null)
|
||||
{
|
||||
separator = FILTER_SEPARATOR;
|
||||
}
|
||||
//Escape any regex chars
|
||||
separator = java.util.regex.Pattern.quote(separator);
|
||||
String[] fqParts = value.split(separator);
|
||||
StringBuffer authorityBuffer = new StringBuffer();
|
||||
int start = fqParts.length / 2;
|
||||
for(int i = start; i < fqParts.length; i++)
|
||||
{
|
||||
String[] split = fqParts[i].split(AUTHORITY_SEPARATOR, 2);
|
||||
if (split.length == 2)
|
||||
{
|
||||
authorityBuffer.append(split[1]);
|
||||
}
|
||||
}
|
||||
if (authorityBuffer.length() > 0)
|
||||
{
|
||||
return authorityBuffer.toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String transformSortValue(Context context, String field, String value) throws SQLException {
|
||||
if(field.equals("location.comm") || field.equals("location.coll"))
|
||||
{
|
||||
value = locationToName(context, field, value);
|
||||
}else
|
||||
if(field.endsWith("_filter"))
|
||||
{
|
||||
//We have a filter make sure we split !
|
||||
String separator = new DSpace().getConfigurationService().getProperty("discovery.solr.facets.split.char");
|
||||
if(separator == null)
|
||||
{
|
||||
separator = FILTER_SEPARATOR;
|
||||
}
|
||||
//Escape any regex chars
|
||||
separator = java.util.regex.Pattern.quote(separator);
|
||||
String[] fqParts = value.split(separator);
|
||||
StringBuffer valueBuffer = new StringBuffer();
|
||||
int end = fqParts.length / 2;
|
||||
for(int i = 0; i < end; i++)
|
||||
{
|
||||
valueBuffer.append(fqParts[i]);
|
||||
}
|
||||
|
@@ -623,7 +623,8 @@ public class PrivateItems extends AbstractDSpaceTransformer implements
|
||||
|
||||
params.scope.setJumpToItem(RequestUtils.getIntParameter(request, BrowseParams.JUMPTO_ITEM));
|
||||
params.scope.setOrder(request.getParameter(BrowseParams.ORDER));
|
||||
params.scope.setOffset(RequestUtils.getIntParameter(request, BrowseParams.OFFSET));
|
||||
int offset = RequestUtils.getIntParameter(request, BrowseParams.OFFSET);
|
||||
params.scope.setOffset(offset > 0 ? offset : 0);
|
||||
params.scope.setResultsPerPage(RequestUtils.getIntParameter(request,
|
||||
BrowseParams.RESULTS_PER_PAGE));
|
||||
params.scope.setStartsWith(request.getParameter(BrowseParams.STARTS_WITH));
|
||||
|
@@ -623,7 +623,8 @@ public class WithdrawnItems extends AbstractDSpaceTransformer implements
|
||||
|
||||
params.scope.setJumpToItem(RequestUtils.getIntParameter(request, BrowseParams.JUMPTO_ITEM));
|
||||
params.scope.setOrder(request.getParameter(BrowseParams.ORDER));
|
||||
params.scope.setOffset(RequestUtils.getIntParameter(request, BrowseParams.OFFSET));
|
||||
int offset = RequestUtils.getIntParameter(request, BrowseParams.OFFSET);
|
||||
params.scope.setOffset(offset > 0 ? offset : 0);
|
||||
params.scope.setResultsPerPage(RequestUtils.getIntParameter(request,
|
||||
BrowseParams.RESULTS_PER_PAGE));
|
||||
params.scope.setStartsWith(request.getParameter(BrowseParams.STARTS_WITH));
|
||||
|
@@ -853,6 +853,25 @@ webui.strengths.cache = false
|
||||
|
||||
|
||||
###### Browse Configuration ######
|
||||
#
|
||||
# Define the DAO class to use this must meet your storage choice for
|
||||
# the browse system (RDBMS: PostgreSQL or Oracle, SOLR).
|
||||
# By default the standard RDBMS implementation for your db is used
|
||||
#
|
||||
# PostgreSQL:
|
||||
# browseDAO.class = org.dspace.browse.BrowseDAOPostgres
|
||||
# browseCreateDAO.class = org.dspace.browse.BrowseCreateDAOPostgres
|
||||
#
|
||||
# Oracle:
|
||||
# browseDAO.class = org.dspace.browse.BrowseDAOOracle
|
||||
# browseCreateDAO.class = org.dspace.browse.BrowseCreateDAOOracle
|
||||
#
|
||||
# SOLR:
|
||||
# browseDAO.class = org.dspace.browse.SolrBrowseDAO
|
||||
# browseCreateDAO.class = org.dspace.browse.SolrBrowseCreateDAO
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Use this to configure the browse indices. Each entry will receive a link in the
|
||||
# navigation. Each entry can be configured in one of two ways. The first is:
|
||||
|
@@ -12,3 +12,7 @@ search.server = http://localhost:8080/solr/search
|
||||
|
||||
#All metadata fields that will not end up in the index, this is a comma separated list
|
||||
index.ignore=dc.description.provenance
|
||||
|
||||
# index.ignore-variants = false
|
||||
# index.ignore-authority = false
|
||||
index.projection=dc.title,dc.contributor.*,dc.date.issued
|
||||
|
@@ -188,4 +188,5 @@
|
||||
<property name="metadataField" value="dc.date.issued"/>
|
||||
<property name="type" value="date"/>
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
</beans>
|
@@ -22,4 +22,9 @@
|
||||
|
||||
<alias name="solrServiceResourceIndexPlugin" alias="org.dspace.discovery.SolrServiceResourceRestrictionPlugin"/>
|
||||
|
||||
<!-- Additional indexing plugin to implement the browse system via SOLR -->
|
||||
<bean id="solrBrowseIndexer" scope="prototype"
|
||||
class="org.dspace.browse.SolrBrowseCreateDAO">
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user