diff options
| -rw-r--r-- | htroot/yacysearchtrailer.html | 17 | ||||
| -rw-r--r-- | htroot/yacysearchtrailer.java | 150 | ||||
| -rw-r--r-- | source/net/yacy/search/navigator/Navigator.java | 96 | ||||
| -rw-r--r-- | source/net/yacy/search/navigator/RestrictedStringNavigator.java | 108 | ||||
| -rw-r--r-- | source/net/yacy/search/navigator/StringNavigator.java | 141 | ||||
| -rw-r--r-- | source/net/yacy/search/query/SearchEvent.java | 68 |
6 files changed, 468 insertions, 112 deletions
diff --git a/htroot/yacysearchtrailer.html b/htroot/yacysearchtrailer.html index 4c10663af..631846e52 100644 --- a/htroot/yacysearchtrailer.html +++ b/htroot/yacysearchtrailer.html @@ -190,23 +190,14 @@ function toggleVisibility(name, count) { <script>if (#[count]# <= 8) toggleVisibility('namespace', #[count]#);</script> #(/nav-namespace)# -#(nav-authors)#:: +#{navs}# <ul class="nav nav-sidebar menugroup"> -<li style="cursor: pointer; cursor: hand;"><h3 onclick="toggleVisibility('authors', #[count]#);">Author [#[count]#] <span style="float:right" id="chevron-authors" class="glyphicon glyphicon-chevron-down" title="click to expand facet"></span></h3></li> +<li style="cursor: pointer; cursor: hand;"><h3 onclick="toggleVisibility('#[name]#', #[count]#);">#[displayname]# [#[count]#] <span style="float:right" id="chevron-#[name]#" class="glyphicon glyphicon-chevron-down" title="click to expand facet"></span></h3></li> #{element}# <li style="display:none" id="#[id]#"><a href="#[url]#" class="MenuItemLink"><input type="checkbox" onchange="window.location.href='#[url]#'"#(on)# checked="checked"::#(/on)#/> #[name]# (#[count]#)</a></li> #{/element}#</ul> -<script>if (#[count]# <= 8) toggleVisibility('authors', #[count]#);</script> -#(/nav-authors)# - -#(nav-collections)#:: -<ul class="nav nav-sidebar menugroup"> -<li style="cursor: pointer; cursor: hand;"><h3 onclick="toggleVisibility('collections', #[count]#);">Collection [#[count]#] <span style="float:right" id="chevron-collections" class="glyphicon glyphicon-chevron-down" title="click to expand facet"></span></h3></li> -#{element}# -<li style="display:none" id="#[id]#"><a href="#[url]#" class="MenuItemLink"><input type="checkbox" onchange="window.location.href='#[url]#'"#(on)# checked="checked"::#(/on)#/> #[name]# (#[count]#)</a></li> -#{/element}#</ul> -<script>if (#[count]# <= 8) toggleVisibility('collections', #[count]#);</script> -#(/nav-collections)# +<script>if (#[count]# <= 8) toggleVisibility('#[name]#', #[count]#);</script> +#{/navs}# #{nav-vocabulary}# <ul class="nav nav-sidebar menugroup"> diff --git a/htroot/yacysearchtrailer.java b/htroot/yacysearchtrailer.java index 2481097dc..6b569f2ef 100644 --- a/htroot/yacysearchtrailer.java +++ b/htroot/yacysearchtrailer.java @@ -19,6 +19,9 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.AbstractMap; import java.util.Date; @@ -41,6 +44,7 @@ import net.yacy.peers.graphics.ProfilingGraph; import net.yacy.search.EventTracker; import net.yacy.search.Switchboard; import net.yacy.search.SwitchboardConstants; +import net.yacy.search.navigator.StringNavigator; import net.yacy.search.query.QueryParams; import net.yacy.search.query.SearchEvent; import net.yacy.search.query.SearchEventCache; @@ -223,90 +227,6 @@ public class yacysearchtrailer { if (pos == 1 && neg == 0) prop.put("nav-languages", 0); // this navigation is not useful } - // author navigators - if (theSearch.authorNavigator == null || theSearch.authorNavigator.isEmpty()) { - prop.put("nav-authors", 0); - } else { - prop.put("nav-authors", 1); - navigatorIterator = theSearch.authorNavigator.keys(false); - int i = 0, pos = 0, neg = 0; - String nav, rawNav; - while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) { - name = navigatorIterator.next().trim(); - count = theSearch.authorNavigator.get(name); - if (count == 0) break; - nav = (name.indexOf(' ', 0) < 0) ? "author%3A" + name : "author%3A%28" + name.replace(" ", "+") + "%29"; - /* Avoid double percent encoding in QueryParams.navurl */ - rawNav = (name.indexOf(' ', 0) < 0) ? "author:" + name : "author:(" + name.replace(" ", "+") + ")"; - if (theSearch.query.modifier.author == null || !theSearch.query.modifier.author.contains(name)) { - pos++; - prop.put("nav-authors_element_" + i + "_on", 1); - prop.put(fileType, "nav-authors_element_" + i + "_modifier", nav); - } else { - neg++; - prop.put("nav-authors_element_" + i + "_on", 0); - prop.put(fileType, "nav-authors_element_" + i + "_modifier", "-" + nav); - nav=""; - rawNav = ""; - } - prop.put(fileType, "nav-authors_element_" + i + "_name", name); - /* URL is already percent encoded : no need to re-encode specifically for the file type */ - prop.put("nav-authors_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString()); - prop.put(fileType, "nav-authors_element_" + i + "_id", "authors_" + i); - prop.put("nav-authors_element_" + i + "_count", count); - prop.put("nav-authors_element_" + i + "_nl", 1); - i++; - } - prop.put("nav-authors_element", i); - prop.put("nav-authors_count", i); - i--; - prop.put("nav-authors_element_" + i + "_nl", 0); - if (pos == 1 && neg == 0) { - prop.put("nav-authors", 0); // this navigation is not useful - } - } - - // collection navigators - if (theSearch.collectionNavigator == null || theSearch.collectionNavigator.isEmpty()) { - prop.put("nav-collections", 0); - } else { - prop.put("nav-collections", 1); - navigatorIterator = theSearch.collectionNavigator.keys(false); - int i = 0, pos = 0, neg = 0; - String nav, rawNav; - while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) { - name = navigatorIterator.next().trim(); - count = theSearch.collectionNavigator.get(name); - if (count == 0) break; - nav = "collection%3A" + name; - /* Avoid double percent encoding in QueryParams.navurl */ - rawNav = "collection:" + name; - if (theSearch.query.modifier.collection == null || !theSearch.query.modifier.collection.contains(name)) { - pos++; - prop.put("nav-collections_element_" + i + "_on", 1); - prop.put(fileType, "nav-collections_element_" + i + "_modifier", nav); - } else { - neg++; - prop.put("nav-collections_element_" + i + "_on", 0); - prop.put(fileType, "nav-collections_element_" + i + "_modifier", "-" + nav); - nav=""; - rawNav = ""; - } - prop.put(fileType, "nav-collections_element_" + i + "_name", name); - /* URL is already percent encoded : no need to re-encode specifically for the file type */ - prop.put("nav-collections_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, true).toString()); - prop.put(fileType, "nav-collections_element_" + i + "_id", "collections_" + i); - prop.put("nav-collections_element_" + i + "_count", count); - prop.put("nav-collections_element_" + i + "_nl", 1); - i++; - } - prop.put("nav-collections_element", i); - prop.put("nav-collections_count", i); - i--; - prop.put("nav-collections_element_" + i + "_nl", 0); - if (pos == 1 && neg == 0) prop.put("nav-collections", 0); // this navigation is not useful - } - // topics navigator final ScoreMap<String> topicNavigator = theSearch.getTopicNavigator(TOPWORDS_MAXCOUNT); if (topicNavigator == null || topicNavigator.isEmpty()) { @@ -545,6 +465,68 @@ public class yacysearchtrailer { prop.put("nav-vocabulary", 0); } + // navigator plugins + int ni = 0; + for (String naviname : theSearch.navigatorPlugins.keySet()) { + + StringNavigator navi = theSearch.navigatorPlugins.get(naviname); + if (navi.isEmpty()) { + continue; + } + + prop.put("navs_" + ni + "_displayname", navi.getDisplayName()); + prop.put("navs_" + ni + "_name", naviname); + prop.put("navs_" + ni + "_count", navi.size()); + + navigatorIterator = navi.keys(false); + int i = 0, pos = 0, neg = 0; + String nav, rawNav; + while (i < QueryParams.FACETS_STANDARD_MAXCOUNT && navigatorIterator.hasNext()) { + name = navigatorIterator.next(); + count = navi.get(name); + if (count == 0) { + break; + } + String encname = ((name.indexOf(' ', 0) < 0) ? name : "(" + name + ")"); + try { + nav = URLEncoder.encode(navi.getQueryModifier() + encname, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException ex) { + nav = ""; + } + + rawNav = navi.getQueryModifier() + encname; + boolean isactive = navi.modifieractive(theSearch.query.modifier, name); + if (!isactive) { + pos++; + prop.put("navs_" + ni + "_element_" + i + "_on", 1); + prop.put(fileType, "navs_" + ni + "_element_" + i + "_modifier", nav); + } else { + neg++; + prop.put("navs_" + ni + "_element_" + i + "_on", 0); + prop.put(fileType, "navs_" + ni + "_element_" + i + "_modifier", "-" + nav); + nav = ""; + rawNav = ""; + } + prop.put(fileType, "navs_" + ni + "_element_" + i + "_name", navi.getElementDisplayName(name)); + // URL is already percent encoded : no need to re-encode specifically for the file type + prop.put("navs_" + ni + "_element_" + i + "_url", QueryParams.navurl(fileType, 0, theSearch.query, rawNav, false).toString()); + prop.put(fileType, "navs_" + ni + "_element_" + i + "_id", naviname + "_" + i); + prop.put("navs_" + ni + "_element_" + i + "_count", count); + prop.put("navs_" + ni + "_element_" + i + "_nl", 1); + i++; + } + prop.put("navs_" + ni + "_element", i); + prop.put("navs_" + ni + "_count", i); + i--; + prop.put("navs_" + ni + "_element_" + i + "_nl", 0); + if (pos == 1 && neg == 0) { + prop.put("navs_" + ni, 0); // this navigation is not useful + } + + ni++; + } + prop.put("navs", ni); // navigatior plugins - eof + // about box final String aboutBody = env.getConfig("about.body", ""); final String aboutHeadline = env.getConfig("about.headline", ""); diff --git a/source/net/yacy/search/navigator/Navigator.java b/source/net/yacy/search/navigator/Navigator.java new file mode 100644 index 000000000..20acd21c9 --- /dev/null +++ b/source/net/yacy/search/navigator/Navigator.java @@ -0,0 +1,96 @@ +/**
+ * Navigator.java
+ * (C) 2016 by reger24; https://github.com/reger24
+ *
+ * This is a part of YaCy, a peer-to-peer based web search engine
+ *
+ * LICENSE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.yacy.search.navigator;
+
+import java.util.List;
+import java.util.Map;
+import net.yacy.cora.sorting.ReversibleScoreMap;
+import net.yacy.cora.sorting.ScoreMap;
+import net.yacy.kelondro.data.meta.URIMetadataNode;
+import net.yacy.search.query.QueryModifier;
+
+/**
+ * Interface for search navigators used in search servlets to restrict displayed
+ * search results.
+ */
+public interface Navigator extends ScoreMap<String> {
+
+ /**
+ * @return name of the navigator for display in ui
+ */
+ public String getDisplayName() ;
+
+ /**
+ * Display form of the element (e.g. for languages the key might be "en",
+ * the display form "English"
+ *
+ * @param key original key as counted in this navigator
+ * @return a translated display text for a key
+ */
+ public String getElementDisplayName(String key) ;
+
+ /**
+ * Returns the query modifier prefix. This is used (needed) within the servlet
+ * to create a new modifier for a activated (clicked) navigator item.
+ *
+ * @return the query modifier prefix (if any, eg. "filetype:" or "author:" )
+ */
+ public String getQueryModifier() ;
+
+ /**
+ * Add counts for this navigator from documents in the provided list.
+ * The navigator looks for a field in the document and increases the counts
+ * depending on the value in the document field.
+ *
+ * @param docs list of documents
+ */
+ public void incDocList(List<URIMetadataNode> docs);
+
+ /**
+ * Add count for this navigator from provided Solr facet map.
+ * The navigator looks for a field in the facet map and increases the counts
+ * by the value in the facet map.
+ *
+ * @param facets Solr facets
+ */
+ public void incFacet(Map<String, ReversibleScoreMap<String>> facets);
+
+ /**
+ * Add count for this navigator from provided document.
+ * The navigator looks for a field in the document and increases the counts
+ * depending on the value in the document field.
+ *
+ * @param docs document
+ */
+ public void incDoc(URIMetadataNode doc);
+
+ /**
+ * Helper routine to determine if current navigator key is part of the query
+ * modifier (is active)
+ *
+ * @param modifier current search query modifier
+ * @param name the navigator key to check
+ * @return true if navigator key is mentioned as modifier
+ */
+ public boolean modifieractive(QueryModifier modifier, String name);
+}
diff --git a/source/net/yacy/search/navigator/RestrictedStringNavigator.java b/source/net/yacy/search/navigator/RestrictedStringNavigator.java new file mode 100644 index 000000000..af3a6aa12 --- /dev/null +++ b/source/net/yacy/search/navigator/RestrictedStringNavigator.java @@ -0,0 +1,108 @@ +/**
+ * RestrictedStringNavigator.java
+ * (C) 2016 by reger24; https://github.com/reger24
+ *
+ * This is a part of YaCy, a peer-to-peer based web search engine
+ *
+ * LICENSE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.yacy.search.navigator;
+
+import java.util.HashSet;
+import java.util.Set;
+import net.yacy.cora.sorting.ScoreMap;
+import net.yacy.search.schema.CollectionSchema;
+
+/**
+ * A Navigator that allows to restrict the items
+ * If allowed items are set only these will be counted or displayed
+ * If forbidden items are set these are excluded from display
+ */
+public class RestrictedStringNavigator extends StringNavigator implements Navigator {
+
+ Set<String> allowed; // complete list of keys, if empty all keys are allowed
+ Set<String> forbidden; // keys to exclude
+
+ public RestrictedStringNavigator(String title, CollectionSchema field) {
+ super(title, field);
+ this.allowed = new HashSet<String>();
+ this.forbidden = new HashSet<String>();
+ }
+
+ /**
+ * Add a allowed navigator key string. If set, only allowed items are displayed
+ * which means you have to add all possible key which sall be allowed.
+ *
+ * @param s key
+ * @return true if added, false if already existed
+ */
+ public boolean addAllowed(String s) {
+ return this.allowed.add(s);
+ }
+
+ /**
+ * Add a blacklisted item which shall be excluded from counting and display.
+ *
+ * @param s key
+ * @return true if added, false if already existed
+ */
+ public boolean addForbidden(String s) {
+ return this.forbidden.add(s);
+ }
+
+ /**
+ * Increase counter if item allowed and not forbidden
+ * @param key
+ */
+ @Override
+ public void inc(final String key) {
+ if (!forbidden.contains(key)) {
+ if (allowed.isEmpty()) {
+ super.inc(key);
+ } else if (allowed.contains(key)) {
+ super.inc(key);
+ }
+ }
+ }
+
+ /**
+ * Increase counter if item allowed and not forbidden
+ * @param key
+ */
+ @Override
+ public void inc(ScoreMap<String> map) {
+ if (map == null) {
+ return;
+ }
+ for (String entry : map) {
+ if (!forbidden.contains(entry)) {
+ if (allowed.isEmpty()) {
+ int count = map.get(entry);
+ if (count > 0) {
+ this.inc(entry, count);
+ }
+ } else if (allowed.contains(entry)) {
+ int count = map.get(entry);
+ if (count > 0) {
+ this.inc(entry, count);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/source/net/yacy/search/navigator/StringNavigator.java b/source/net/yacy/search/navigator/StringNavigator.java new file mode 100644 index 000000000..a3049cddd --- /dev/null +++ b/source/net/yacy/search/navigator/StringNavigator.java @@ -0,0 +1,141 @@ +/**
+ * Navigator.java
+ * (C) 2016 by reger24; https://github.com/reger24
+ *
+ * This is a part of YaCy, a peer-to-peer based web search engine
+ *
+ * LICENSE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.yacy.search.navigator;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import net.yacy.cora.federate.solr.SolrType;
+import net.yacy.cora.sorting.ConcurrentScoreMap;
+import net.yacy.cora.sorting.ReversibleScoreMap;
+import net.yacy.kelondro.data.meta.URIMetadataNode;
+import net.yacy.search.query.QueryModifier;
+import net.yacy.search.schema.CollectionSchema;
+
+/**
+ *
+ */
+public class StringNavigator extends ConcurrentScoreMap<String> implements Navigator {
+
+ public String title;
+ public CollectionSchema field;
+
+ public StringNavigator(String title, CollectionSchema field) {
+ super();
+ this.title = title;
+ this.field = field;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return title;
+ }
+
+ @Override
+ public String getElementDisplayName(String e) {
+ return e;
+ }
+
+ @Override
+ public String getQueryModifier() {
+ String mod;
+ if (field != null) {
+ switch (field) {
+ case author_sxt:
+ mod = "author:";
+ break;
+ case url_protocol_s:
+ mod = "/";
+ break;
+ case url_file_ext_s:
+ mod = "filetype:";
+ break;
+ case collection_sxt:
+ mod = "collection:";
+ break;
+ case host_s:
+ mod = "site:";
+ break;
+ case language_s:
+ mod = "/language/";
+ break;
+ default:
+ mod = ":";
+ }
+ } else {
+ mod = ":";
+ }
+ return mod;
+ }
+
+ @Override
+ public void incDocList(List<URIMetadataNode> docs) {
+ if (field != null) {
+ for (URIMetadataNode doc : docs) {
+ incDoc(doc);
+ }
+ }
+ }
+
+ @Override
+ public void incFacet(Map<String, ReversibleScoreMap<String>> facets) {
+ if (field != null && facets != null && !facets.isEmpty()) {
+ ReversibleScoreMap<String> fcts = facets.get(field.getSolrFieldName());
+ if (fcts != null) {
+ this.inc(fcts);
+ }
+ }
+ }
+
+ @Override
+ public void incDoc(URIMetadataNode doc) {
+ if (field != null) {
+ if (field.getType() == SolrType.date) {
+ Date dd = (Date) doc.getFieldValue(field.getSolrFieldName());
+ String year = Integer.toString(dd.getYear() + 1900);
+ this.inc(year);
+ } else {
+ Object val = doc.getFieldValue(field.getSolrFieldName());
+ if (val instanceof List) {
+ List<String> ll = (List) val;
+ for (String s : ll) {
+ this.inc(s);
+ }
+ } else {
+ if (val != null) {
+ this.inc((String) val);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean modifieractive(QueryModifier modifier, String name) {
+ if (name.indexOf(' ') < 0) {
+ return modifier.toString().contains(getQueryModifier() + name);
+ } else {
+ return modifier.toString().contains(getQueryModifier() + "(" + name + ")");
+ }
+ }
+}
diff --git a/source/net/yacy/search/query/SearchEvent.java b/source/net/yacy/search/query/SearchEvent.java index bac4d5794..260ddc790 100644 --- a/source/net/yacy/search/query/SearchEvent.java +++ b/source/net/yacy/search/query/SearchEvent.java @@ -68,6 +68,7 @@ import net.yacy.cora.sorting.WeakPriorityBlockingQueue.ReverseElement; import net.yacy.cora.storage.HandleSet; import net.yacy.cora.util.ConcurrentLog; import net.yacy.cora.util.SpaceExceededException; +import net.yacy.crawler.CrawlSwitchboard; import net.yacy.crawler.retrieval.Response; import net.yacy.data.WorkTables; import net.yacy.document.LargeNumberCache; @@ -97,6 +98,9 @@ import net.yacy.search.EventTracker; import net.yacy.search.Switchboard; import net.yacy.search.SwitchboardConstants; import net.yacy.search.index.Segment; +import net.yacy.search.navigator.Navigator; +import net.yacy.search.navigator.RestrictedStringNavigator; +import net.yacy.search.navigator.StringNavigator; import net.yacy.search.ranking.ReferenceOrder; import net.yacy.search.schema.CollectionConfiguration; import net.yacy.search.schema.CollectionSchema; @@ -144,8 +148,6 @@ public final class SearchEvent { private final AtomicInteger expectedRemoteReferences, maxExpectedRemoteReferences; // counter for referenced that had been sorted out for other reasons public final ScoreMap<String> locationNavigator; // a counter for the appearance of location coordinates public final ScoreMap<String> hostNavigator; // a counter for the appearance of host names - public final ScoreMap<String> authorNavigator; // a counter for the appearances of authors - public final ScoreMap<String> collectionNavigator; // a counter for the appearances of collections public final ScoreMap<String> namespaceNavigator; // a counter for name spaces public final ScoreMap<String> protocolNavigator; // a counter for protocol types public final ScoreMap<String> filetypeNavigator; // a counter for file types @@ -153,6 +155,8 @@ public final class SearchEvent { public final ScoreMap<String> languageNavigator; // a counter for appearance of languages public final Map<String, ScoreMap<String>> vocabularyNavigator; // counters for Vocabularies; key is metatag.getVocabularyName() private final int topicNavigatorCount; // if 0 no topicNavigator, holds expected number of terms for the topicNavigator + // map of search custom/configured search navigators in addition to above standard navigators (which use special handling or display forms) + public final Map<String, StringNavigator> navigatorPlugins; // map of active search navigators key=internal navigator name private final LoaderDispatcher loader; private final HandleSet snippetFetchWordHashes; // a set of word hashes that are used to match with the snippets private final boolean deleteIfSnippetFail; @@ -257,8 +261,6 @@ public final class SearchEvent { // prepare configured search navigation final String navcfg = Switchboard.getSwitchboard().getConfig("search.navigation", ""); this.locationNavigator = navcfg.contains("location") ? new ConcurrentScoreMap<String>() : null; - this.authorNavigator = navcfg.contains("authors") ? new ConcurrentScoreMap<String>() : null; - this.collectionNavigator = navcfg.contains("collections") ? new ConcurrentScoreMap<String>() : null; this.namespaceNavigator = navcfg.contains("namespace") ? new ConcurrentScoreMap<String>() : null; this.hostNavigator = navcfg.contains("hosts") ? new ConcurrentScoreMap<String>() : null; this.protocolNavigator = navcfg.contains("protocol") ? new ConcurrentScoreMap<String>() : null; @@ -267,6 +269,31 @@ public final class SearchEvent { this.topicNavigatorCount = navcfg.contains("topics") ? MAX_TOPWORDS : 0; this.languageNavigator = navcfg.contains("language") ? new ConcurrentScoreMap<String>() : null; this.vocabularyNavigator = new TreeMap<String, ScoreMap<String>>(); + // prepare configured search navigation (plugins) + this.navigatorPlugins = new LinkedHashMap<String, StringNavigator>(); + String[] navnames = navcfg.split(","); + for (String navname : navnames) { + if (navname.contains("authors")) { + this.navigatorPlugins.put("authors", new StringNavigator("Authors", CollectionSchema.author_sxt)); + } + if (navname.contains("collections")) { + RestrictedStringNavigator tmpnav = new RestrictedStringNavigator("Collection", CollectionSchema.collection_sxt); + // exclude default internal collection names + tmpnav.addForbidden("dht"); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_AUTOCRAWL_DEEP); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_AUTOCRAWL_SHALLOW); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_PROXY); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_REMOTE); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_SNIPPET_LOCAL_TEXT); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_SNIPPET_GLOBAL_TEXT); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_GREEDY_LEARNING_TEXT); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_SNIPPET_LOCAL_MEDIA); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_SNIPPET_GLOBAL_MEDIA); + tmpnav.addForbidden("robot_" + CrawlSwitchboard.CRAWL_PROFILE_SURROGATE); + this.navigatorPlugins.put("collections", tmpnav); + } + } + this.snippets = new ConcurrentHashMap<String, LinkedHashSet<String>>(); this.secondarySearchSuperviser = (this.query.getQueryGoal().getIncludeHashes().size() > 1) ? new SecondarySearchSuperviser(this) : null; // generate abstracts only for combined searches if (this.secondarySearchSuperviser != null) this.secondarySearchSuperviser.start(); @@ -813,6 +840,19 @@ public final class SearchEvent { timer = System.currentTimeMillis(); // collect navigation information + + // iterate over active navigator plugins to let them update the counters + for (String s : this.navigatorPlugins.keySet()) { + Navigator navi = this.navigatorPlugins.get(s); + if (navi != null) { + if (facets == null || facets.isEmpty()) { // just in case we got no solr facet + navi.incDocList(nodeList); + } else { + navi.incFacet(facets); + } + } + } + ReversibleScoreMap<String> fcts; if (this.locationNavigator != null) { fcts = facets.get(CollectionSchema.coordinate_p_0_coordinate.getSolrFieldName()); @@ -834,7 +874,6 @@ public final class SearchEvent { if (host.startsWith("www.")) host = host.substring(4); this.hostNavigator.inc(host, hc); } - //this.hostNavigator.inc(fcts); } } @@ -879,16 +918,6 @@ public final class SearchEvent { } } - if (this.authorNavigator != null) { - fcts = facets.get(CollectionSchema.author_sxt.getSolrFieldName()); - if (fcts != null) this.authorNavigator.inc(fcts); - } - - if (this.collectionNavigator != null) { - fcts = facets.get(CollectionSchema.collection_sxt.getSolrFieldName()); - if (fcts != null) this.collectionNavigator.inc(fcts); - } - if (this.protocolNavigator != null) { fcts = facets.get(CollectionSchema.url_protocol_s.getSolrFieldName()); if (fcts != null) { @@ -1303,6 +1332,15 @@ public final class SearchEvent { } // from here: collect navigation information + // TODO: it may be a little bit late here, to update navigator counters + + // iterate over active navigator plugins (the rwi metadata may contain the field the plugin counts) + for (String s : this.navigatorPlugins.keySet()) { + Navigator navi = this.navigatorPlugins.get(s); + if (navi != null) { + navi.incDoc(page); + } + } // namespace navigation if (this.namespaceNavigator != null) { |
