summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--htroot/yacysearchtrailer.html17
-rw-r--r--htroot/yacysearchtrailer.java150
-rw-r--r--source/net/yacy/search/navigator/Navigator.java96
-rw-r--r--source/net/yacy/search/navigator/RestrictedStringNavigator.java108
-rw-r--r--source/net/yacy/search/navigator/StringNavigator.java141
-rw-r--r--source/net/yacy/search/query/SearchEvent.java68
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) {