Author: ssmiweve
Date: 2009-02-25 00:48:13 +0100 (Wed, 25 Feb 2009)
New Revision: 7208
Added:
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/FacetedSearchConfigurationDeserializer.java
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/FacetedCommandConfig.java
Modified:
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/SolrCommandConfig.java
branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSearchCommand.java
branches/2.18/mojo/src/main/java/no/sesat/mojo/modes/Builder.java
branches/2.18/query-transform-control-spi/src/main/java/no/sesat/search/query/transform/QueryTransformer.java
branches/2.18/result-spi/src/main/java/no/sesat/search/result/Navigator.java
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/CommandConfig.java
Log:
Support for Command Facets. Particularly Solr's SimpleFacetToolkit
Added:
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/FacetedSearchConfigurationDeserializer.java
===================================================================
---
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/FacetedSearchConfigurationDeserializer.java
(rev 0)
+++
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/FacetedSearchConfigurationDeserializer.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -0,0 +1,112 @@
+/*
+ * 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.mode.config;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import no.sesat.search.result.Navigator;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/** UTility class to deserialise facets.
+ *
+ * @version $Id$
+ */
+final class FacetedSearchConfigurationDeserializer {
+
+ private static final Logger LOG =
Logger.getLogger(FacetedSearchConfigurationDeserializer.class);
+
+ private static final String ERR_ONLY_ONE_CHILD_FACET_ALLOWED
+ = "Each Facet is only allowed to have one child. Parent was ";
+
+ private static final String INFO_PARSING_FACET = " Parsing facet ";
+
+ /** Currently only used by the subclasses but hopefully open to all one
day.
+ * @param navsE w3c dom elements to deserialise
+ * @return collection of Navigators
+ */
+ static final Collection<Navigator> parseNavigators(final Element navsE) {
+
+ final Collection<Navigator> navigators = new ArrayList<Navigator>();
+ final NodeList children = navsE.getChildNodes();
+ for (int i = 0; i < children.getLength(); ++i) {
+ final Node child = children.item(i);
+ if (child instanceof Element && "facet".equals(((Element)
child).getTagName())) {
+ final Element navE = (Element) child;
+ final String id = navE.getAttribute("id");
+ final String name = navE.getAttribute("name");
+ final String sortAttr = navE.getAttribute("sort") != null &&
navE.getAttribute("sort").length() > 0
+ ? navE.getAttribute("sort").toUpperCase() : "COUNT";
+ LOG.info(INFO_PARSING_FACET + id + " [" + name + "]" + ",
sort=" + sortAttr);
+ final Navigator.Sort sort = Navigator.Sort.valueOf(sortAttr);
+
+ final boolean boundaryMatch =
navE.getAttribute("boundary-match").equals("true");
+
+ final Navigator nav = new Navigator(
+ name,
+ navE.getAttribute("field"),
+ navE.getAttribute("display-name"),
+ sort,
+ boundaryMatch);
+ nav.setId(id);
+ final Collection<Navigator> childNavigators =
parseNavigators(navE);
+ if (childNavigators.size() > 1) {
+ throw new
IllegalStateException(ERR_ONLY_ONE_CHILD_FACET_ALLOWED + id);
+ } else if (childNavigators.size() == 1) {
+ nav.setChildNavigator(childNavigators.iterator().next());
+ }
+ navigators.add(nav);
+ }
+ }
+
+ return navigators;
+ }
+
+ static final void readNavigators(
+ final Element element,
+ final FacetedCommandConfig config,
+ final SearchConfiguration inherit,
+ final Map<String, Navigator> facets){
+
+ final FacetedCommandConfig navCmdInherit = inherit instanceof
FacetedCommandConfig
+ ? (FacetedCommandConfig) inherit
+ : null;
+
+ if (null != navCmdInherit && null != navCmdInherit.getFacets()) {
+
+ facets.putAll(navCmdInherit.getFacets());
+ }
+
+ final NodeList nList = element.getElementsByTagName("facets");
+
+ for (int i = 0; i < nList.getLength(); ++i) {
+ final Collection<Navigator> navs = parseNavigators((Element)
nList.item(i));
+ for (Navigator navigator : navs) {
+ facets.put(navigator.getId(), navigator);
+ }
+ }
+ }
+
+ private FacetedSearchConfigurationDeserializer(){}
+
+}
Property changes on:
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/FacetedSearchConfigurationDeserializer.java
___________________________________________________________________
Added: svn:keywords
+ Id
Modified:
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/SolrCommandConfig.java
===================================================================
---
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/SolrCommandConfig.java
2009-02-24 23:42:05 UTC (rev 7207)
+++
branches/2.18/generic.sesam/search-command-config/src/main/java/no/sesat/search/mode/config/SolrCommandConfig.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -1,4 +1,4 @@
-/* Copyright (2008) Schibsted Søk AS
+/* Copyright (2008-2009) Schibsted Søk AS
* This file is part of SESAT.
*
* SESAT is free software: you can redistribute it and/or modify
@@ -26,6 +26,7 @@
import java.util.Map;
import no.sesat.search.mode.SearchModeFactory.Context;
import no.sesat.search.mode.config.CommandConfig.Controller;
+import no.sesat.search.result.Navigator;
import org.w3c.dom.Element;
/** Searching against a Solr index using the Solrj client.
@@ -33,9 +34,8 @@
* @version $Id$
*/
@Controller("SolrSearchCommand")
-public class SolrCommandConfig extends CommandConfig {
+public class SolrCommandConfig extends CommandConfig implements
FacetedCommandConfig {
-
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
@@ -48,6 +48,10 @@
private Integer timeout = Integer.MAX_VALUE;
+ private final Map<String, Navigator> facets = new
HashMap<String,Navigator>();
+
+ private String facetToolkit;
+
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
@@ -138,7 +142,34 @@
return timeout;
}
+ /**
+ *
+ * @return
+ */
@Override
+ public Map<String, Navigator> getFacets() {
+ return facets;
+ }
+
+ /**
+ *
+ * @param navigatorKey
+ * @return
+ */
+ @Override
+ public Navigator getFacet(final String navigatorKey) {
+ return facets.get(navigatorKey);
+ }
+
+ public String getFacetToolkit() {
+ return facetToolkit;
+ }
+
+ public void setFacetToolkit(final String toolkit){
+ this.facetToolkit = toolkit;
+ }
+
+ @Override
public SearchConfiguration readSearchConfiguration(
final Element element,
final SearchConfiguration inherit,
@@ -156,6 +187,8 @@
}
}
+ FacetedSearchConfigurationDeserializer.readNavigators(element, this,
inherit, facets);
+
return this;
}
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-02-24 23:42:05 UTC (rev 7207)
+++
branches/2.18/generic.sesam/search-command-control/default/src/main/java/no/sesat/search/mode/command/SolrSearchCommand.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -1,5 +1,5 @@
/*
- * Copyright (2008) Schibsted Søk AS
+ * Copyright (2008-2009) Schibsted Søk AS
* This file is part of SESAT.
*
* SESAT is free software: you can redistribute it and/or modify
@@ -24,9 +24,13 @@
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import no.sesat.commons.ref.ReferenceMap;
+import no.sesat.search.datamodel.generic.StringDataObject;
+import no.sesat.search.datamodel.request.ParametersDataObject;
+import no.sesat.search.mode.config.FacetedCommandConfig;
import no.sesat.search.mode.config.SolrCommandConfig;
import no.sesat.search.result.BasicResultItem;
import no.sesat.search.result.BasicResultList;
+import no.sesat.search.result.Navigator;
import no.sesat.search.result.ResultItem;
import no.sesat.search.result.ResultList;
import no.sesat.search.site.config.SiteConfiguration;
@@ -57,6 +61,7 @@
// Attributes ----------------------------------------------------
private SolrServer server;
+ private final FacetToolkit facetToolkit;
// Static --------------------------------------------------------
@@ -85,6 +90,8 @@
} catch (MalformedURLException ex) {
LOG.error(ex.getMessage(), ex);
}
+
+ facetToolkit = new SimpleFacetToolkitImpl();
}
// Public --------------------------------------------------------
@@ -103,6 +110,8 @@
.setRows(getSearchConfiguration().getResultsToReturn())
.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());
@@ -143,7 +152,31 @@
// Protected -----------------------------------------------------
+ protected FacetToolkit createFacetToolkit(){
+ FacetToolkit toolkit = null;
+ final String toolkitName = getSearchConfiguration().getFacetToolkit();
+ if(null != toolkit){
+ try{
+ final Class<FacetToolkit> cls = (Class<FacetToolkit>)
Class.forName(toolkitName);
+ toolkit = cls.newInstance();
+ }catch(ClassNotFoundException cnfe){
+ LOG.error(cnfe.getMessage());
+ }catch(InstantiationException ie){
+ LOG.error(ie.getMessage());
+ }catch(IllegalAccessException iae){
+ LOG.error(iae.getMessage());
+ }
+ }
+ return toolkit;
+ }
+
+ protected final void createFacets(final SolrQuery query){
+ if(null != facetToolkit){
+ facetToolkit.createFacets(context, query);
+ }
+ }
+
protected BasicResultItem createItem(final SolrDocument doc) {
BasicResultItem item = new BasicResultItem();
@@ -160,4 +193,55 @@
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
+
+ /**
+ * Provider to add facets from request to SolrQuery.
+ */
+ public interface FacetToolkit{
+ void createFacets(SearchCommand.Context context, SolrQuery query);
+ }
+
+ /**
+ * Solr's Simple Faceting toolkit.
+ *
+ * {...@link http://wiki.apache.org/solr/SolrFacetingOverview}
+ * {...@link http://wiki.apache.org/solr/SimpleFacetParameters}
+ */
+ public static class SimpleFacetToolkitImpl implements FacetToolkit{
+
+ 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 selection
+ for (final Navigator facet : facets.values()) {
+
+ 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.addFacetQuery(facet.getField() + ':' + value);
+ }
+ }
+ }
+ }
+
+ private FacetedCommandConfig getSearchConfiguration(final
SearchCommand.Context context){
+ return (FacetedCommandConfig) context.getSearchConfiguration();
+ }
+ }
}
Modified: branches/2.18/mojo/src/main/java/no/sesat/mojo/modes/Builder.java
===================================================================
--- branches/2.18/mojo/src/main/java/no/sesat/mojo/modes/Builder.java
2009-02-24 23:42:05 UTC (rev 7207)
+++ branches/2.18/mojo/src/main/java/no/sesat/mojo/modes/Builder.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -1,5 +1,5 @@
/*
- * Copyright (2008) Schibsted Søk AS
+ * Copyright (2008-2009) Schibsted Søk AS
* This file is part of SESAT.
*
* SESAT is free software: you can redistribute it and/or modify
@@ -200,6 +200,8 @@
final ConfigElement navigators = new ConfigElement("navigators");
final ConfigElement navigator = new ConfigElement("navigator");
+ final ConfigElement facets = new ConfigElement("facets");
+ final ConfigElement facet = new ConfigElement("facet");
// TODO replace with introspection
navigator.getAttributes().add(new ConfigAttribute("id", null, true));
navigator.getAttributes().add(new ConfigAttribute("name", null, true));
@@ -207,18 +209,22 @@
navigator.getAttributes().add(new ConfigAttribute("display-name",
null, true));
navigator.getAttributes().add(new ConfigAttribute("sort", null,
false));
navigator.getAttributes().add(new ConfigAttribute("boundary-match"));
+ facet.getAttributes().addAll(navigator.getAttributes());
// allow recursive nesting of navigator.
navigator.addChild(navigator);
-
// only for fast commands
navigators.addChild(navigator);
+ facet.addChild(facet);
+ facets.addChild(facet);
+
for (ConfigElement command : commands) {
command.addChild(queryBuilder);
command.addChild(resultHandler);
command.addChild(queryTransform);
command.addChild(navigators);
+ command.addChild(facets);
}
final Runnable[] jobs = {new GenerateRelaxNG(modes, outputDir +
"modes.rnc", id),
Modified:
branches/2.18/query-transform-control-spi/src/main/java/no/sesat/search/query/transform/QueryTransformer.java
===================================================================
---
branches/2.18/query-transform-control-spi/src/main/java/no/sesat/search/query/transform/QueryTransformer.java
2009-02-24 23:42:05 UTC (rev 7207)
+++
branches/2.18/query-transform-control-spi/src/main/java/no/sesat/search/query/transform/QueryTransformer.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -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
@@ -30,6 +30,7 @@
import org.w3c.dom.Element;
import java.util.Map;
+import no.sesat.search.mode.config.SearchConfiguration;
/**
@@ -109,7 +110,9 @@
* <p/>
* +docdatetime:>2005-10-28
*
- * @param parameters
+ * @deprecated all functionality should be provided by getFilter() with
any access to parameters via the datamodel
+ *
+ * @param parameters the datamodel's parameters
* @return filterstring
*/
String getFilter(Map parameters);
Modified:
branches/2.18/result-spi/src/main/java/no/sesat/search/result/Navigator.java
===================================================================
---
branches/2.18/result-spi/src/main/java/no/sesat/search/result/Navigator.java
2009-02-24 23:42:05 UTC (rev 7207)
+++
branches/2.18/result-spi/src/main/java/no/sesat/search/result/Navigator.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -23,6 +23,8 @@
*
* Each facet contains an id, name, displayName, sort definition,
boundaryMatch enabled, and children navigators.
*
+ * @todo rename to Facet
+ *
* @version <tt>$Id$</tt>
*/
public final class Navigator implements Serializable {
@@ -37,8 +39,8 @@
public enum Sort {
- COUNT(),
- YEAR(),
+ COUNT,
+ YEAR,
MONTH_YEAR(),
DAY_MONTH_YEAR(),
DAY_MONTH_YEAR_DESCENDING,
Modified:
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/CommandConfig.java
===================================================================
---
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/CommandConfig.java
2009-02-24 23:42:05 UTC (rev 7207)
+++
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/CommandConfig.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -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
@@ -362,6 +362,8 @@
/** Currently only used by the fast subclasses but hopefully open to all
one day. *
* @param navsE w3c dom elements to deserialise
* @return collection of Navigators
+ *
+ * @deprecated Use FacetedCommandConfigUtility.parseNavigators(Element)
instead.
*/
protected final Collection<Navigator> parseNavigators(final Element navsE)
{
Added:
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/FacetedCommandConfig.java
===================================================================
---
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/FacetedCommandConfig.java
(rev 0)
+++
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/FacetedCommandConfig.java
2009-02-24 23:48:13 UTC (rev 7208)
@@ -0,0 +1,43 @@
+/*
+ * 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.mode.config;
+
+import java.util.Map;
+import no.sesat.search.result.Navigator;
+
+/**
+ *
+ * @version $Id$
+ */
+public interface FacetedCommandConfig extends SearchConfiguration{
+
+ /**
+ *
+ * @param navigatorKey
+ * @return
+ */
+ Navigator getFacet(final String navigatorKey);
+
+ /**
+ *
+ * @return
+ */
+ Map<String, Navigator> getFacets();
+}
Property changes on:
branches/2.18/search-command-config-spi/src/main/java/no/sesat/search/mode/config/FacetedCommandConfig.java
___________________________________________________________________
Added: svn:keywords
+ Id
_______________________________________________
Kernel-commits mailing list
[email protected]
http://sesat.no/mailman/listinfo/kernel-commits