Author: ssmiweve Date: 2009-03-04 16:44:28 +0100 (Wed, 04 Mar 2009) New Revision: 7217
Added: branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResult.java branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResultImpl.java Modified: branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FastSearchResult.java branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSearchCommand.java branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSimpleFacetToolkitImpl.java branches/2.18/generic.sesam/view-control/src/main/java/no/sesat/search/view/navigation/fast/FastNavigationController.java Log: Solr additions: - facet navigations via SolrSimpleFacetToolkitImpl & FacetedSearchResult (FastSearchResult is no deprecated) - user sorting Added: branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResult.java =================================================================== --- branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResult.java (rev 0) +++ branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResult.java 2009-03-04 15:44:28 UTC (rev 7217) @@ -0,0 +1,64 @@ +/* Copyright (2009) Schibsted Søk AS + * This file is part of SESAT. + * + * SESAT is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SESAT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with SESAT. If not, see <http://www.gnu.org/licenses/>. + */ +package no.sesat.search.result; + +import java.util.List; + +/** An extension of ResultList that stores the facets from a facet enabled search command. + * + * @version $Id$ + */ +public interface FacetedSearchResult<T extends ResultItem> extends ResultList<T>{ + + /** + * To the list of modifiers found in the navigators under the name "navigatorName" + * add the modifier. + * + * @param navigatorName + * @param modifier + */ + void addModifier(final String navigatorName, final Modifier modifier); + + /** + * The modifier with name "modifierName" from the modifier list + * found in the navigation map under the name "navigatorNam". + * + * @param navigatorName + * @param modifierName + * @return the modifier found,or null + */ + Modifier getModifier(final String navigatorName, final String modifierName); + + /** + * The count of the modifier with name "modifierName" from the modifier list + * found in the navigation map under the name "navigatorNam". + * + * @param navigatorName + * @param modifierName + * @return + */ + int getModifierCount(final String navigatorName, final String modifierName); + + /** + * A live copy of the modifiers found in the navigation map under the name "navigatorName". + * + * @param navigatorName + * @return + */ + List<Modifier> getModifiers(final String navigatorName); + +} Property changes on: branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResult.java ___________________________________________________________________ Added: svn:keywords + Id Added: branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResultImpl.java =================================================================== --- branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResultImpl.java (rev 0) +++ branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResultImpl.java 2009-03-04 15:44:28 UTC (rev 7217) @@ -0,0 +1,94 @@ +/* Copyright (2009) Schibsted Søk AS + * This file is part of SESAT. + * + * SESAT is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SESAT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with SESAT. If not, see <http://www.gnu.org/licenses/>. + + */ +package no.sesat.search.result; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** An extension of BasicResultList that provides navigators (which hold modifiers), and currentNavigators. + * + * @param <T> The each ResultItem classes that are used. + * @version <tt>$Id$</tt> + */ +public class FacetedSearchResultImpl<T extends ResultItem> extends BasicResultList<T> implements FacetedSearchResult<T>{ + + // Attributes ---------------------------------------------------- + + private final Map<String,List<Modifier>> modifiers = new HashMap<String,List<Modifier>>(); + + // Constructors -------------------------------------------------- + + /** + * Default constructor. + */ + public FacetedSearchResultImpl() {} + + // Public -------------------------------------------------------- + + public void addModifier(final String navigatorName, final Modifier modifier) { + + final List<Modifier> mods; + + if (!modifiers.containsKey(navigatorName)) { + mods = new ArrayList<Modifier>(); + modifiers.put(navigatorName, mods); + } else { + mods = modifiers.get(navigatorName); + } + + mods.add(modifier); + } + + public List<Modifier> getModifiers(final String navigatorName) { + return modifiers.get(navigatorName); + } + + public Modifier getModifier(final String navigatorName, final String modifierName) { + + final List<Modifier> mods = getModifiers(navigatorName); + + if (mods != null) { + for (final Iterator iterator = mods.iterator(); iterator.hasNext();) { + final Modifier modifier = (Modifier) iterator.next(); + if (modifier.getName().equals(modifierName)) { + return modifier; + } + } + } + + return null; + } + + public int getModifierCount(final String navigatorName, final String modifierName) { + + final Modifier modifier = getModifier(navigatorName, modifierName); + return modifier != null ? modifier.getCount(): 0; + } + + // Package protected --------------------------------------------- + + // Protected ----------------------------------------------------- + + // Private ------------------------------------------------------- + +} Property changes on: branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FacetedSearchResultImpl.java ___________________________________________________________________ Added: svn:keywords + Id Modified: branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FastSearchResult.java =================================================================== --- branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FastSearchResult.java 2009-03-04 08:51:11 UTC (rev 7216) +++ branches/2.18/generic.sesam/result/src/main/java/no/sesat/search/result/FastSearchResult.java 2009-03-04 15:44:28 UTC (rev 7217) @@ -1,4 +1,4 @@ -/* Copyright (2006-2008) Schibsted Søk AS +/* Copyright (2006-2009) Schibsted Søk AS * This file is part of SESAT. * * SESAT is free software: you can redistribute it and/or modify @@ -18,95 +18,21 @@ package no.sesat.search.result; -import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; /** An override of BasicResultList that provides navigators (which hold modifiers), and currentNavigators. * + * @deprecated Nothing Fast specific here. Use instead FacetedSearchResultImpl. + * * @param <T> The each ResultItem classes that are used. * @version <tt>$Id$</tt> */ -public class FastSearchResult<T extends ResultItem> extends BasicResultList<T>{ +public class FastSearchResult<T extends ResultItem> extends FacetedSearchResultImpl<T>{ - private Map<String,List<Modifier>> navigators = new HashMap<String,List<Modifier>>(); private Map<String,Navigator> currentNavigators = new HashMap<String,Navigator>(); - - /** - * Default constructor. - */ - public FastSearchResult() {} - - /** To the list of modifiers found in the navigators under the name "navigatorName" - * add the modifier. - * - * @param navigatorName - * @param modifier - */ - public void addModifier(final String navigatorName, final Modifier modifier) { - - final List<Modifier> modifiers; - - if (!navigators.containsKey(navigatorName)) { - modifiers = new ArrayList<Modifier>(); - navigators.put(navigatorName, modifiers); - } else { - modifiers = navigators.get(navigatorName); - } - - modifiers.add(modifier); - } - - - /** A live copy of the modifiers found in the navigation map under the name "navigatorNam". - * - * @param navigatorName - * @return - */ - public List<Modifier> getModifiers(final String navigatorName) { - return navigators.get(navigatorName); - } - - /** The modifier with name "modifierName" from the modifier list - * found in the navigation map under the name "navigatorNam". - * - * @param navigatorName - * @param modifierName - * @return the modifier found,or null - */ - public Modifier getModifier(final String navigatorName, final String modifierName) { - - final List modifiers = getModifiers(navigatorName); - - if (modifiers != null) { - for (final Iterator iterator = modifiers.iterator(); iterator.hasNext();) { - final Modifier modifier = (Modifier) iterator.next(); - if (modifier.getName().equals(modifierName)) { - return modifier; - } - } - } - - return null; - } - - /** The count of the modifier with name "modifierName" from the modifier list - * found in the navigation map under the name "navigatorNam". - * - * @param navigatorName - * @param modifierName - * @return - */ - public int getModifierCount(final String navigatorName, final String modifierName) { - - final Modifier modifier = getModifier(navigatorName, modifierName); - return modifier != null ? modifier.getCount(): 0; - } - /** Add a current Navigator * * @param currentNavigator Modified: branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSearchCommand.java =================================================================== --- branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSearchCommand.java 2009-03-04 08:51:11 UTC (rev 7216) +++ branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSearchCommand.java 2009-03-04 15:44:28 UTC (rev 7217) @@ -29,6 +29,9 @@ import no.sesat.search.mode.config.SolrCommandConfig; import no.sesat.search.result.BasicResultItem; import no.sesat.search.result.BasicResultList; +import no.sesat.search.result.FacetedSearchResult; +import no.sesat.search.result.FacetedSearchResultImpl; +import no.sesat.search.result.Navigator; import no.sesat.search.result.ResultItem; import no.sesat.search.result.ResultList; import no.sesat.search.site.Site; @@ -100,43 +103,19 @@ @Override public ResultList<ResultItem> execute() { - final ResultList<ResultItem> searchResult = new BasicResultList<ResultItem>(); + final ResultList<ResultItem> searchResult = null != facetToolkit + ? new FacetedSearchResultImpl<ResultItem>() + : new BasicResultList<ResultItem>(); - // @todo make the join between query and filter configurable - final String q = getTransformedQuery() - + (0 < getFilter().length() ? " (" + getFilter() + ')' : ""); - try { // set up query final SolrQuery query = new SolrQuery() - .setQuery(q) - .setFilterQueries(getSearchConfiguration().getFilteringQuery()) + .setQuery(getTransformedQuery()) .setStart(getOffset()) .setRows(getSearchConfiguration().getResultsToReturn()); - // custom query type - if(null != getSearchConfiguration().getQueryType() && 0 < getSearchConfiguration().getQueryType().length()){ - query.setQueryType(getSearchConfiguration().getQueryType()); - } + modifyQuery(query); - // The request handler may be configured in the index which fields to return in the results - if(0 < getSearchConfiguration().getResultFieldMap().size()){ - query.setFields(getSearchConfiguration().getResultFieldMap().keySet().toArray(new String[]{})); - } - - createFacets(query); - - // when the root logger is set to DEBUG do not limit connection times - if(Logger.getRootLogger().getLevel().isGreaterOrEqual(Level.INFO)){ - query.setTimeAllowed(getSearchConfiguration().getTimeout()); - } - - final Map<String,String> sortMap = getSearchConfiguration().getSortMap(); - for(Map.Entry<String,String> entry : sortMap.entrySet()){ - final SolrQuery.ORDER order = SolrQuery.ORDER.valueOf(entry.getValue()); - query.addSortField(entry.getKey(), order); - } - DUMP.info(query.toString()); // query @@ -147,10 +126,11 @@ // iterate through docs for(SolrDocument doc : docs){ - searchResult.addResult(createItem(doc)); } + collectFacets(response, searchResult); + } catch (SolrServerException ex) { LOG.error(ex.getMessage(), ex); } @@ -166,6 +146,56 @@ // Protected ----------------------------------------------------- + /** Override this to set additional parameters in the SolrQuery. + * Crucial for any override to call super.modifyQuery(query) + **/ + protected void modifyQuery(final SolrQuery query){ + + // @XXX does this ruin solr caching + query.set("uniqueId", context.getDataModel().getParameters().getUniqueId()); + + // add any filtering query + if(0 < getSearchConfiguration().getFilteringQuery().length()){ + query.setFilterQueries(getSearchConfiguration().getFilteringQuery()); + } + + // also add any filter + if(0 < getFilter().length()){ + query.addFilterQuery(getFilter()); + } + + // custom query type + if(null != getSearchConfiguration().getQueryType() && 0 < getSearchConfiguration().getQueryType().length()){ + query.setQueryType(getSearchConfiguration().getQueryType()); + } + + // The request handler may be configured in the index which fields to return in the results + if(0 < getSearchConfiguration().getResultFieldMap().size()){ + query.setFields(getSearchConfiguration().getResultFieldMap().keySet().toArray(new String[]{})); + } + + createFacets(query); + + // when the root logger is set to DEBUG do not limit connection times + if(Logger.getRootLogger().getLevel().isGreaterOrEqual(Level.INFO)){ + query.setTimeAllowed(getSearchConfiguration().getTimeout()); + } + + // sorting + if(isUserSortable()){ + final String sort = getUserSortBy(); + if(null != sort){ + final String[] sortSplit = sort.split(" "); + query.addSortField(sortSplit[0], SolrQuery.ORDER.valueOf(sortSplit[1])); + } + } + final Map<String,String> sortMap = getSearchConfiguration().getSortMap(); + for(Map.Entry<String,String> entry : sortMap.entrySet()){ + final SolrQuery.ORDER order = SolrQuery.ORDER.valueOf(entry.getValue()); + query.addSortField(entry.getKey(), order); + } + } + protected FacetToolkit createFacetToolkit(){ FacetToolkit toolkit = null; @@ -182,6 +212,13 @@ } } + protected final void collectFacets(final QueryResponse response, final ResultList<ResultItem> searchResult){ + + if(null != facetToolkit && searchResult instanceof FacetedSearchResult){ + facetToolkit.collectFacets(context, response, (FacetedSearchResult<? extends ResultItem>)searchResult); + } + } + protected BasicResultItem createItem(final SolrDocument doc) { Map<String,String> fieldNames; @@ -221,7 +258,12 @@ * Provider to add facets from request to SolrQuery. */ public interface FacetToolkit{ + void createFacets(SearchCommand.Context context, SolrQuery query); + void collectFacets( + SearchCommand.Context context, + QueryResponse response, + FacetedSearchResult<? extends ResultItem> searchResult); } protected static final class FacetToolkitFactory { Modified: branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSimpleFacetToolkitImpl.java =================================================================== --- branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSimpleFacetToolkitImpl.java 2009-03-04 08:51:11 UTC (rev 7216) +++ branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSimpleFacetToolkitImpl.java 2009-03-04 15:44:28 UTC (rev 7217) @@ -20,8 +20,13 @@ import java.util.Map; import no.sesat.search.datamodel.generic.StringDataObject; import no.sesat.search.mode.config.FacetedCommandConfig; +import no.sesat.search.result.FacetedSearchResult; +import no.sesat.search.result.Modifier; import no.sesat.search.result.Navigator; +import no.sesat.search.result.ResultItem; import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.response.FacetField; +import org.apache.solr.client.solrj.response.QueryResponse; /** * Solr's Simple Faceting toolkit. @@ -31,30 +36,61 @@ */ public class SolrSimpleFacetToolkitImpl implements SolrSearchCommand.FacetToolkit { + // Constructors -------------------------------------------------- + + // Public -------------------------------------------------------- + public void createFacets(final SearchCommand.Context context, final SolrQuery query) { final Map<String, Navigator> facets = getSearchConfiguration(context).getFacets(); query.setFacet(0 < facets.size()); - // facet counters - for (Navigator facet : facets.values()) { - query.addFacetField(facet.getField()); + // facet counters || selection + for (final Navigator facet : facets.values()) { + createFacet(context, facet, query); } + } - // facet selection + public void collectFacets( + final SearchCommand.Context context, + final QueryResponse response, + final FacetedSearchResult<? extends ResultItem> searchResult) { + + final Map<String, Navigator> facets = getSearchConfiguration(context).getFacets(); for (final Navigator facet : facets.values()) { - final StringDataObject facetValue = context.getDataModel().getParameters().getValue(facet.getId()); + final FacetField field = response.getFacetField(facet.getId()); + // facet counters + if(null != field && null != field.getValues()){ + for (FacetField.Count c : field.getValues()){ + final Modifier mod = new Modifier(c.getName(), (int)c.getCount(), facet); + searchResult.addModifier(facet.getId(), mod); + } + } + } + } - if (null != facetValue) { - // splitting here allows for multiple navigation selections within the one navigation level. - for (String navSingleValue : facetValue.getString().split(",")) { + // Package protected --------------------------------------------- - final String value = facet.isBoundaryMatch() - ? "^\"" + navSingleValue + "\"$" - : "\"" + navSingleValue + "\""; + // Protected ----------------------------------------------------- - query.addFacetQuery(facet.getField() + ':' + value); - } + // Private ------------------------------------------------------- + + private void createFacet(final SearchCommand.Context context, final Navigator facet, final SolrQuery query){ + + // we want the facet count + query.addFacetField(facet.getField()); + + final StringDataObject facetValue = context.getDataModel().getParameters().getValue(facet.getId()); + + if (null != facetValue) { + // splitting here allows for multiple navigation selections within the one navigation level. + for (String navSingleValue : facetValue.getString().split(",")) { + + final String value = facet.isBoundaryMatch() + ? "^\"" + navSingleValue + "\"$" + : "\"" + navSingleValue + "\""; + + query.addFilterQuery(facet.getField() + ':' + value); } } } @@ -62,4 +98,7 @@ private FacetedCommandConfig getSearchConfiguration(final SearchCommand.Context context) { return (FacetedCommandConfig) context.getSearchConfiguration(); } + + // Inner classes ------------------------------------------------- + } Modified: branches/2.18/generic.sesam/view-control/src/main/java/no/sesat/search/view/navigation/fast/FastNavigationController.java =================================================================== --- branches/2.18/generic.sesam/view-control/src/main/java/no/sesat/search/view/navigation/fast/FastNavigationController.java 2009-03-04 08:51:11 UTC (rev 7216) +++ branches/2.18/generic.sesam/view-control/src/main/java/no/sesat/search/view/navigation/fast/FastNavigationController.java 2009-03-04 15:44:28 UTC (rev 7217) @@ -30,13 +30,15 @@ import no.sesat.search.datamodel.generic.StringDataObject; import java.util.List; +import no.sesat.search.result.FacetedSearchResult; +import no.sesat.search.result.FacetedSearchResultImpl; import no.sesat.search.view.navigation.FastNavigationConfig; import org.apache.log4j.Logger; /** The Controller class for navigation items generated from a Faceted Search Command's Modifiers. * This will construct a BasicNavigationItem for every Modifier found in the ResultList. * - * @todo RENAME to ModifierNavigationController + * @todo RENAME to FacetNavigationController */ public class FastNavigationController implements NavigationController { @@ -66,9 +68,9 @@ final ResultList<ResultItem> searchResult = search.getResults(); - if (searchResult instanceof FastSearchResult) { + if (searchResult instanceof FacetedSearchResult) { - final FastSearchResult fsr = (FastSearchResult) searchResult; + final FacetedSearchResult fsr = (FacetedSearchResult) searchResult; final List<Modifier> modifiers = fsr.getModifiers(nav.getId()); _______________________________________________ Kernel-commits mailing list Kernel-commits@sesat.no http://sesat.no/mailman/listinfo/kernel-commits