lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jbern...@apache.org
Subject svn commit: r1601664 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/search/ core/src/test-files/solr/collection1/conf/ core/src/test/org/apache/solr/search/
Date Tue, 10 Jun 2014 15:08:49 GMT
Author: jbernste
Date: Tue Jun 10 15:08:48 2014
New Revision: 1601664

URL: http://svn.apache.org/r1601664
Log:
 SOLR-6150: Add new AnalyticsQuery to support pluggable analytics

Added:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java   (with
props)
    lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-analytics-query.xml
  (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
  (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsQueryTest.java   (with
props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestAnalyticsQParserPlugin.java
  (with props)
Modified:
    lucene/dev/trunk/solr/CHANGES.txt

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1601664&r1=1601663&r2=1601664&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Tue Jun 10 15:08:48 2014
@@ -132,6 +132,9 @@ New Features
   supported by he xml, json, and javabin response formats.
   (Varun Thacker via hossman)
 
+* SOLR-6150: Add new AnalyticsQuery to support pluggable analytics
+  (Joel Bernstein)
+
 
 Bug Fixes
 ----------------------

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java?rev=1601664&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java Tue Jun
10 15:08:48 2014
@@ -0,0 +1,81 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.apache.solr.search;
+
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.solr.handler.component.ResponseBuilder;
+import org.apache.solr.handler.component.MergeStrategy;
+import org.apache.solr.request.SolrRequestInfo;
+
+/**
+ *  <b>Note: This API is experimental and may change in non backward-compatible ways
in the future</b>
+ **/
+
+public abstract class AnalyticsQuery extends ExtendedQueryBase implements PostFilter {
+
+  public boolean getCache() {
+    return false;
+  }
+
+  public int getCost() {
+    return Math.max(super.getCost(), 100);
+  }
+
+  public boolean equals(Object o) {
+    return this == o ;
+  }
+
+  public int hashCode() {
+    return System.identityHashCode(this);
+  }
+
+  /**
+  *  Use this constructor for single node analytics.
+  * */
+  public AnalyticsQuery() {
+
+  }
+
+  /**
+   * Use this constructor for distributed analytics.
+   * @param mergeStrategy defines the distributed merge strategy for this AnalyticsQuery
+   **/
+
+  public AnalyticsQuery(MergeStrategy mergeStrategy){
+    SolrRequestInfo info = SolrRequestInfo.getRequestInfo();
+    ResponseBuilder rb = info.getResponseBuilder();
+    rb.addMergeStrategy(mergeStrategy);
+  }
+
+  public DelegatingCollector getFilterCollector(IndexSearcher searcher) {
+    SolrRequestInfo info = SolrRequestInfo.getRequestInfo();
+    ResponseBuilder rb = null;
+    if(info != null) {
+      rb = info.getResponseBuilder();
+    }
+
+    if(rb == null) {
+      //This is the autowarming case.
+      return new DelegatingCollector();
+    } else {
+      return getAnalyticsCollector(rb, searcher);
+    }
+  }
+
+  public abstract DelegatingCollector getAnalyticsCollector(ResponseBuilder rb, IndexSearcher
searcher);
+}
\ No newline at end of file

Added: lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-analytics-query.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-analytics-query.xml?rev=1601664&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-analytics-query.xml
(added)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-analytics-query.xml
Tue Jun 10 15:08:48 2014
@@ -0,0 +1,579 @@
+<?xml version="1.0" ?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is a "kitchen sink" config file that tests can use.
+     When writting a new test, feel free to add *new* items (plugins,
+     config options, etc...) as long as they don't break any existing
+     tests.  if you need to test something esoteric please add a new
+     "solrconfig-your-esoteric-purpose.xml" config file.
+
+     Note in particular that this test is used by MinimalSchemaTest so
+     Anything added to this file needs to work correctly even if there
+     is now uniqueKey or defaultSearch Field.
+  -->
+
+<config>
+
+  <jmx />
+
+  <!-- Used to specify an alternate directory to hold all index data.
+       It defaults to "index" if not present, and should probably
+       not be changed if replication is in use. -->
+  <dataDir>${solr.data.dir:}</dataDir>
+
+  <!--  The DirectoryFactory to use for indexes.
+        solr.StandardDirectoryFactory, the default, is filesystem based.
+        solr.RAMDirectoryFactory is memory based and not persistent. -->
+  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}">
+    <double name="maxWriteMBPerSecDefault">1000000</double>
+    <double name="maxWriteMBPerSecFlush">2000000</double>
+    <double name="maxWriteMBPerSecMerge">3000000</double>
+    <double name="maxWriteMBPerSecRead">4000000</double>
+  </directoryFactory>
+
+  <luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
+
+  <xi:include href="solrconfig.snippet.randomindexconfig.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+  <updateHandler class="solr.DirectUpdateHandler2">
+
+    <!-- autocommit pending docs if certain criteria are met
+    <autoCommit>
+      <maxDocs>10000</maxDocs>
+      <maxTime>3600000</maxTime>
+    </autoCommit>
+    -->
+    <!-- represents a lower bound on the frequency that commits may
+    occur (in seconds). NOTE: not yet implemented
+
+    <commitIntervalLowerBound>0</commitIntervalLowerBound>
+    -->
+
+    <!-- The RunExecutableListener executes an external command.
+         exe - the name of the executable to run
+         dir - dir to use as the current working directory. default="."
+         wait - the calling thread waits until the executable returns. default="true"
+         args - the arguments to pass to the program.  default=nothing
+         env - environment variables to set.  default=nothing
+      -->
+    <!-- A postCommit event is fired after every commit
+    <listener event="postCommit" class="solr.RunExecutableListener">
+      <str name="exe">/var/opt/resin3/__PORT__/scripts/solr/snapshooter</str>
+      <str name="dir">/var/opt/resin3/__PORT__</str>
+      <bool name="wait">true</bool>
+      <arr name="args"> <str>arg1</str> <str>arg2</str> </arr>
+      <arr name="env"> <str>MYVAR=val1</str> </arr>
+    </listener>
+    -->
+
+    <updateLog enable="${enable.update.log:true}">
+      <str name="dir">${solr.ulog.dir:}</str>
+    </updateLog>
+
+    <commitWithin>
+      <softCommit>${solr.commitwithin.softcommit:true}</softCommit>
+    </commitWithin>
+
+  </updateHandler>
+
+  <query>
+    <!-- Maximum number of clauses in a boolean query... can affect
+        range or wildcard queries that expand to big boolean
+        queries.  An exception is thrown if exceeded.
+    -->
+    <maxBooleanClauses>1024</maxBooleanClauses>
+
+    <!-- Cache specification for Filters or DocSets - unordered set of *all* documents
+         that match a particular query.
+      -->
+    <filterCache
+        class="solr.search.FastLRUCache"
+        size="512"
+        initialSize="512"
+        autowarmCount="2"/>
+
+    <queryResultCache
+        class="solr.search.LRUCache"
+        size="512"
+        initialSize="512"
+        autowarmCount="2"/>
+
+    <documentCache
+        class="solr.search.LRUCache"
+        size="512"
+        initialSize="512"
+        autowarmCount="0"/>
+
+    <cache name="perSegFilter"
+           class="solr.search.LRUCache"
+           size="10"
+           initialSize="0"
+           autowarmCount="10" />
+
+    <!-- If true, stored fields that are not requested will be loaded lazily.
+    -->
+    <enableLazyFieldLoading>true</enableLazyFieldLoading>
+
+    <!--
+
+    <cache name="myUserCache"
+      class="solr.search.LRUCache"
+      size="4096"
+      initialSize="1024"
+      autowarmCount="1024"
+      regenerator="MyRegenerator"
+      />
+    -->
+
+    <!--
+    <useFilterForSortedQuery>true</useFilterForSortedQuery>
+    -->
+
+    <queryResultWindowSize>10</queryResultWindowSize>
+
+    <!-- set maxSize artificially low to exercise both types of sets -->
+    <HashDocSet maxSize="3" loadFactor="0.75"/>
+
+    <!-- boolToFilterOptimizer converts boolean clauses with zero boost
+         into cached filters if the number of docs selected by the clause exceeds
+         the threshold (represented as a fraction of the total index)
+    -->
+    <boolTofilterOptimizer enabled="false" cacheSize="32" threshold=".05"/>
+
+    <!-- a newSearcher event is fired whenever a new searcher is being prepared
+         and there is a current searcher handling requests (aka registered). -->
+    <!-- QuerySenderListener takes an array of NamedList and executes a
+         local query request for each NamedList in sequence. -->
+    <!--
+    <listener event="newSearcher" class="solr.QuerySenderListener">
+      <arr name="queries">
+        <lst> <str name="q">solr</str> <str name="start">0</str>
<str name="rows">10</str> </lst>
+        <lst> <str name="q">rocks</str> <str name="start">0</str>
<str name="rows">10</str> </lst>
+      </arr>
+    </listener>
+    -->
+
+    <!-- a firstSearcher event is fired whenever a new searcher is being
+         prepared but there is no current registered searcher to handle
+         requests or to gain prewarming data from. -->
+    <!--
+    <listener event="firstSearcher" class="solr.QuerySenderListener">
+      <arr name="queries">
+        <lst> <str name="q">fast_warm</str> <str name="start">0</str>
<str name="rows">10</str> </lst>
+      </arr>
+    </listener>
+    -->
+
+  </query>
+
+  <queryResponseWriter name="xml" default="true"
+                       class="solr.XMLResponseWriter" />
+
+  <requestHandler name="/replication" class="solr.ReplicationHandler" startup="lazy" />
+
+  <!-- An alternate set representation that uses an integer hash to store filters (sets
of docids).
+If the set cardinality <= maxSize elements, then HashDocSet will be used instead of the
bitset
+based HashBitset. -->
+
+  <!-- requestHandler plugins... incoming queries will be dispatched to the
+     correct handler based on the 'qt' param matching the
+     name of registered handlers.
+      The "standard" request handler is the default and will be used if qt
+     is not specified in the request.
+  -->
+  <requestHandler name="standard" class="solr.StandardRequestHandler">
+    <bool name="httpCaching">true</bool>
+  </requestHandler>
+
+  <requestHandler name="/get" class="solr.RealTimeGetHandler">
+    <lst name="defaults">
+      <str name="omitHeader">true</str>
+    </lst>
+  </requestHandler>
+
+  <requestHandler name="dismax" class="solr.SearchHandler" >
+    <lst name="defaults">
+      <str name="defType">dismax</str>
+      <str name="q.alt">*:*</str>
+      <float name="tie">0.01</float>
+      <str name="qf">
+        text^0.5 features_t^1.0 subject^1.4 title_stemmed^2.0
+      </str>
+      <str name="pf">
+        text^0.2 features_t^1.1 subject^1.4 title_stemmed^2.0 title^1.5
+      </str>
+      <str name="bf">
+        ord(weight)^0.5 recip(rord(iind),1,1000,1000)^0.3
+      </str>
+      <str name="mm">
+        3&lt;-1 5&lt;-2 6&lt;90%
+      </str>
+      <int name="ps">100</int>
+    </lst>
+  </requestHandler>
+
+  <requestHandler name="mock" class="org.apache.solr.core.MockQuerySenderListenerReqHandler"/>
+
+  <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
+
+  <!-- test query parameter defaults -->
+  <requestHandler name="defaults" class="solr.StandardRequestHandler">
+    <lst name="defaults">
+      <int name="rows">4</int>
+      <bool name="hl">true</bool>
+      <str name="hl.fl">text,name,subject,title,whitetok</str>
+    </lst>
+  </requestHandler>
+
+  <!-- test query parameter defaults -->
+  <requestHandler name="lazy" class="solr.StandardRequestHandler" startup="lazy">
+    <lst name="defaults">
+      <int name="rows">4</int>
+      <bool name="hl">true</bool>
+      <str name="hl.fl">text,name,subject,title,whitetok</str>
+    </lst>
+  </requestHandler>
+
+  <requestHandler name="/update" class="solr.UpdateRequestHandler"  />
+
+  <searchComponent name="spellcheck" class="org.apache.solr.handler.component.SpellCheckComponent">
+    <!-- This is slightly different from the field value so we can test dealing with token
offset changes -->
+    <str name="queryAnalyzerFieldType">lowerpunctfilt</str>
+
+    <lst name="spellchecker">
+      <str name="name">default</str>
+      <str name="field">lowerfilt</str>
+      <str name="spellcheckIndexDir">spellchecker1</str>
+      <str name="buildOnCommit">false</str>
+    </lst>
+    <lst name="spellchecker">
+      <str name="name">direct</str>
+      <str name="classname">DirectSolrSpellChecker</str>
+      <str name="field">lowerfilt</str>
+      <int name="minQueryLength">3</int>
+    </lst>
+    <lst name="spellchecker">
+      <str name="name">wordbreak</str>
+      <str name="classname">solr.WordBreakSolrSpellChecker</str>
+      <str name="field">lowerfilt</str>
+      <str name="combineWords">true</str>
+      <str name="breakWords">true</str>
+      <int name="maxChanges">10</int>
+    </lst>
+    <lst name="spellchecker">
+      <str name="name">multipleFields</str>
+      <str name="field">lowerfilt1and2</str>
+      <str name="spellcheckIndexDir">spellcheckerMultipleFields</str>
+      <str name="buildOnCommit">false</str>
+    </lst>
+    <!-- Example of using different distance measure -->
+    <lst name="spellchecker">
+      <str name="name">jarowinkler</str>
+      <str name="field">lowerfilt</str>
+      <!-- Use a different Distance Measure -->
+      <str name="distanceMeasure">org.apache.lucene.search.spell.JaroWinklerDistance</str>
+      <str name="spellcheckIndexDir">spellchecker2</str>
+
+    </lst>
+    <lst name="spellchecker">
+      <str name="classname">solr.FileBasedSpellChecker</str>
+      <str name="name">external</str>
+      <str name="sourceLocation">spellings.txt</str>
+      <str name="characterEncoding">UTF-8</str>
+      <str name="spellcheckIndexDir">spellchecker3</str>
+    </lst>
+    <!-- Comparator -->
+    <lst name="spellchecker">
+      <str name="name">freq</str>
+      <str name="field">lowerfilt</str>
+      <str name="spellcheckIndexDir">spellcheckerFreq</str>
+      <!-- comparatorClass be one of:
+        1. score (default)
+        2. freq (Frequency first, then score)
+        3. A fully qualified class name
+       -->
+      <str name="comparatorClass">freq</str>
+      <str name="buildOnCommit">false</str>
+    </lst>
+    <lst name="spellchecker">
+      <str name="name">fqcn</str>
+      <str name="field">lowerfilt</str>
+      <str name="spellcheckIndexDir">spellcheckerFQCN</str>
+      <str name="comparatorClass">org.apache.solr.spelling.SampleComparator</str>
+      <str name="buildOnCommit">false</str>
+    </lst>
+    <lst name="spellchecker">
+      <str name="name">perDict</str>
+      <str name="classname">org.apache.solr.handler.component.DummyCustomParamSpellChecker</str>
+      <str name="field">lowerfilt</str>
+    </lst>
+  </searchComponent>
+
+  <searchComponent name="termsComp" class="org.apache.solr.handler.component.TermsComponent"/>
+
+  <requestHandler name="/terms" class="org.apache.solr.handler.component.SearchHandler">
+    <arr name="components">
+      <str>termsComp</str>
+    </arr>
+  </requestHandler>
+  <!--
+  The SpellingQueryConverter to convert raw (CommonParams.Q) queries into tokens.  Uses a
simple regular expression
+   to strip off field markup, boosts, ranges, etc. but it is not guaranteed to match an exact
parse from the query parser.
+   -->
+  <queryConverter name="queryConverter" class="org.apache.solr.spelling.SpellingQueryConverter"/>
+
+  <requestHandler name="spellCheckCompRH" class="org.apache.solr.handler.component.SearchHandler">
+    <lst name="defaults">
+      <!-- omp = Only More Popular -->
+      <str name="spellcheck.onlyMorePopular">false</str>
+      <!-- exr = Extended Results -->
+      <str name="spellcheck.extendedResults">false</str>
+      <!--  The number of suggestions to return -->
+      <str name="spellcheck.count">1</str>
+    </lst>
+    <arr name="last-components">
+      <str>spellcheck</str>
+    </arr>
+  </requestHandler>
+  <requestHandler name="spellCheckCompRH_Direct" class="org.apache.solr.handler.component.SearchHandler">
+    <lst name="defaults">
+      <str name="spellcheck.dictionary">direct</str>
+      <str name="spellcheck.onlyMorePopular">false</str>
+      <str name="spellcheck.extendedResults">false</str>
+      <str name="spellcheck.count">1</str>
+    </lst>
+    <arr name="last-components">
+      <str>spellcheck</str>
+    </arr>
+  </requestHandler>
+  <requestHandler name="spellCheckWithWordbreak" class="org.apache.solr.handler.component.SearchHandler">
+    <lst name="defaults">
+      <str name="spellcheck.dictionary">default</str>
+      <str name="spellcheck.dictionary">wordbreak</str>
+      <str name="spellcheck.count">20</str>
+    </lst>
+    <arr name="last-components">
+      <str>spellcheck</str>
+    </arr>
+  </requestHandler>
+  <requestHandler name="spellCheckWithWordbreak_Direct" class="org.apache.solr.handler.component.SearchHandler">
+    <lst name="defaults">
+      <str name="spellcheck.dictionary">direct</str>
+      <str name="spellcheck.dictionary">wordbreak</str>
+      <str name="spellcheck.count">20</str>
+    </lst>
+    <arr name="last-components">
+      <str>spellcheck</str>
+    </arr>
+  </requestHandler>
+  <requestHandler name="spellCheckCompRH1" class="org.apache.solr.handler.component.SearchHandler">
+    <lst name="defaults">
+      <str name="defType">dismax</str>
+      <str name="qf">lowerfilt1^1</str>
+    </lst>
+    <arr name="last-components">
+      <str>spellcheck</str>
+    </arr>
+  </requestHandler>
+
+  <requestHandler name="mltrh" class="org.apache.solr.handler.component.SearchHandler">
+
+  </requestHandler>
+
+  <searchComponent name="tvComponent" class="org.apache.solr.handler.component.TermVectorComponent"/>
+
+  <requestHandler name="tvrh" class="org.apache.solr.handler.component.SearchHandler">
+    <lst name="defaults">
+
+    </lst>
+    <arr name="last-components">
+      <str>tvComponent</str>
+    </arr>
+  </requestHandler>
+
+  <!-- test elevation -->
+  <searchComponent name="elevate" class="org.apache.solr.handler.component.QueryElevationComponent"
>
+    <str name="queryFieldType">string</str>
+    <str name="config-file">elevate.xml</str>
+  </searchComponent>
+
+
+  <requestHandler name="/elevate" class="org.apache.solr.handler.component.SearchHandler">
+    <lst name="defaults">
+      <str name="echoParams">explicit</str>
+    </lst>
+    <arr name="last-components">
+      <str>elevate</str>
+    </arr>
+  </requestHandler>
+
+  <requestHandler name="/mlt" class="solr.MoreLikeThisHandler">
+  </requestHandler>
+
+
+  <searchComponent class="solr.HighlightComponent" name="highlight">
+    <highlighting>
+      <!-- Configure the standard fragmenter -->
+      <fragmenter name="gap" class="org.apache.solr.highlight.GapFragmenter" default="true">
+        <lst name="defaults">
+          <int name="hl.fragsize">100</int>
+        </lst>
+      </fragmenter>
+
+      <fragmenter name="regex" class="org.apache.solr.highlight.RegexFragmenter">
+        <lst name="defaults">
+          <int name="hl.fragsize">70</int>
+        </lst>
+      </fragmenter>
+
+      <!-- Configure the standard formatter -->
+      <formatter name="html" class="org.apache.solr.highlight.HtmlFormatter" default="true">
+        <lst name="defaults">
+          <str name="hl.simple.pre"><![CDATA[<em>]]></str>
+          <str name="hl.simple.post"><![CDATA[</em>]]></str>
+        </lst>
+      </formatter>
+
+      <!-- Configure the standard fragListBuilder -->
+      <fragListBuilder name="simple" class="org.apache.solr.highlight.SimpleFragListBuilder"
default="true"/>
+
+      <!-- Configure the standard fragmentsBuilder -->
+      <fragmentsBuilder name="simple" class="org.apache.solr.highlight.SimpleFragmentsBuilder"
default="true"/>
+      <fragmentsBuilder name="scoreOrder" class="org.apache.solr.highlight.ScoreOrderFragmentsBuilder"/>
+
+      <boundaryScanner name="simple" class="solr.highlight.SimpleBoundaryScanner" default="true">
+        <lst name="defaults">
+          <str name="hl.bs.maxScan">10</str>
+          <str name="hl.bs.chars">.,!? &#9;&#10;&#13;</str>
+        </lst>
+      </boundaryScanner>
+
+      <boundaryScanner name="breakIterator" class="solr.highlight.BreakIteratorBoundaryScanner">
+        <lst name="defaults">
+          <str name="hl.bs.type">WORD</str>
+          <str name="hl.bs.language">en</str>
+          <str name="hl.bs.country">US</str>
+        </lst>
+      </boundaryScanner>
+    </highlighting>
+  </searchComponent>
+
+  <!-- enable streaming for testing... -->
+  <requestDispatcher handleSelect="true" >
+    <requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048" />
+    <httpCaching lastModifiedFrom="openTime" etagSeed="Solr" never304="false">
+      <cacheControl>max-age=30, public</cacheControl>
+    </httpCaching>
+  </requestDispatcher>
+
+  <!-- Echo the request contents back to the client -->
+  <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >
+    <lst name="defaults">
+      <str name="echoParams">explicit</str>
+      <str name="echoHandler">true</str>
+    </lst>
+  </requestHandler>
+
+  <admin>
+    <defaultQuery>solr</defaultQuery>
+    <gettableFiles>solrconfig.xml schema.xml admin-extra.html</gettableFiles>
+  </admin>
+
+  <!-- test getting system property -->
+  <propTest attr1="${solr.test.sys.prop1}-$${literal}"
+            attr2="${non.existent.sys.prop:default-from-config}">prefix-${solr.test.sys.prop2}-suffix</propTest>
+
+  <queryParser name="count" class="org.apache.solr.search.TestAnalyticsQParserPlugin"/>
+
+  <updateRequestProcessorChain name="dedupe">
+    <processor class="org.apache.solr.update.processor.SignatureUpdateProcessorFactory">
+      <bool name="enabled">false</bool>
+      <bool name="overwriteDupes">true</bool>
+      <str name="fields">v_t,t_field</str>
+      <str name="signatureClass">org.apache.solr.update.processor.TextProfileSignature</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+  <updateRequestProcessorChain name="dedupe-allfields">
+    <processor class="org.apache.solr.update.processor.SignatureUpdateProcessorFactory">
+      <bool name="enabled">false</bool>
+      <bool name="overwriteDupes">false</bool>
+      <str name="signatureField">id</str>
+      <str name="fields"></str>
+      <str name="signatureClass">org.apache.solr.update.processor.Lookup3Signature</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+  <updateRequestProcessorChain name="stored_sig">
+    <!-- this chain is valid even though the signature field is not
+         indexed, because we are not asking for dups to be overwritten
+      -->
+    <processor class="org.apache.solr.update.processor.SignatureUpdateProcessorFactory">
+      <bool name="enabled">true</bool>
+      <str name="signatureField">non_indexed_signature_sS</str>
+      <bool name="overwriteDupes">false</bool>
+      <str name="fields">v_t,t_field</str>
+      <str name="signatureClass">org.apache.solr.update.processor.TextProfileSignature</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+  <updateRequestProcessorChain name="uniq-fields">
+    <processor class="org.apache.solr.update.processor.UniqFieldsUpdateProcessorFactory">
+      <arr name="fieldName">
+        <str>uniq</str>
+        <str>uniq2</str>
+        <str>uniq3</str>
+      </arr>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+
+  <updateRequestProcessorChain name="distrib-dup-test-chain-explicit">
+    <!-- explicit test using processors before and after distrib -->
+    <processor class="solr.RegexReplaceProcessorFactory">
+      <str name="fieldName">regex_dup_A_s</str>
+      <str name="pattern">x</str>
+      <str name="replacement">x_x</str>
+    </processor>
+    <processor class="solr.DistributedUpdateProcessorFactory" />
+    <processor class="solr.RegexReplaceProcessorFactory">
+      <str name="fieldName">regex_dup_B_s</str>
+      <str name="pattern">x</str>
+      <str name="replacement">x_x</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+
+  <updateRequestProcessorChain name="distrib-dup-test-chain-implicit">
+    <!-- implicit test w/o distrib declared-->
+    <processor class="solr.RegexReplaceProcessorFactory">
+      <str name="fieldName">regex_dup_A_s</str>
+      <str name="pattern">x</str>
+      <str name="replacement">x_x</str>
+    </processor>
+    <processor class="solr.RegexReplaceProcessorFactory">
+      <str name="fieldName">regex_dup_B_s</str>
+      <str name="pattern">x</str>
+      <str name="replacement">x_x</str>
+    </processor>
+    <processor class="solr.RunUpdateProcessorFactory" />
+  </updateRequestProcessorChain>
+
+</config>
+

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java?rev=1601664&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
(added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
Tue Jun 10 15:08:48 2014
@@ -0,0 +1,87 @@
+package org.apache.solr.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.solr.BaseDistributedSearchTestCase;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.junit.BeforeClass;
+
+import java.util.Arrays;
+
+/**
+ * Test for QueryComponent's distributed querying
+ *
+ * @see org.apache.solr.handler.component.QueryComponent
+ */
+public class AnalyticsMergeStrategyTest extends BaseDistributedSearchTestCase {
+
+  public AnalyticsMergeStrategyTest() {
+    fixShardCount = true;
+    shardCount = 3;
+    stress = 0;
+  }
+
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception {
+    initCore("solrconfig-analytics-query.xml", "schema15.xml");
+  }
+
+  @Override
+  public void doTest() throws Exception {
+    del("*:*");
+
+    index_specific(0,"id","1", "sort_i", "5");
+    index_specific(0,"id","2", "sort_i", "50");
+    index_specific(1,"id","5", "sort_i", "4");
+    index_specific(1,"id","6", "sort_i", "10");
+    index_specific(0,"id","7", "sort_i", "1");
+    index_specific(1,"id","8", "sort_i", "2");
+    index_specific(2,"id","9", "sort_i", "1000");
+    index_specific(2,"id","10", "sort_i", "1500");
+    index_specific(2,"id","11", "sort_i", "1300");
+    index_specific(1,"id","12", "sort_i", "15");
+    index_specific(1,"id","13", "sort_i", "16");
+
+    commit();
+
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add("q", "*:*");
+    params.add("fq", "{!count}");
+    setDistributedParams(params);
+    QueryResponse rsp = queryServer(params);
+    assertCount(rsp, 11);
+
+    params = new ModifiableSolrParams();
+    params.add("q", "id:(1 2 5 6)");
+    params.add("fq", "{!count}");
+    setDistributedParams(params);
+    rsp = queryServer(params);
+    assertCount(rsp, 4);
+  }
+
+  private void assertCount(QueryResponse rsp, int count) throws Exception {
+    NamedList response = rsp.getResponse();
+    NamedList analytics = (NamedList)response.get("analytics");
+    Integer c = (Integer)analytics.get("mycount");
+    if(c.intValue() != count) {
+      throw new Exception("Count is not correct:"+count+":"+c.intValue());
+    }
+  }
+}

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsQueryTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsQueryTest.java?rev=1601664&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsQueryTest.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/AnalyticsQueryTest.java Tue
Jun 10 15:08:48 2014
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.search;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class AnalyticsQueryTest extends SolrTestCaseJ4 {
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig-analytics-query.xml", "schema15.xml");
+  }
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+    // if you override setUp or tearDown, you better call
+    // the super classes version
+    super.setUp();
+    clearIndex();
+    assertU(commit());
+  }
+
+
+  @Test
+  public void testAnalyticsQuery() throws Exception {
+
+    String[] doc = {"id","1", "sort_i", "100"};
+    assertU(adoc(doc));
+    assertU(commit());
+    String[] doc1 = {"id","2", "sort_i", "50"};
+    assertU(adoc(doc1));
+
+
+
+    String[] doc2 = {"id","3", "sort_i", "1000"};
+    assertU(adoc(doc2));
+    assertU(commit());
+    String[] doc3 = {"id","4", "sort_i", "2000"};
+    assertU(adoc(doc3));
+
+
+    String[] doc4 = {"id","5", "sort_i", "2"};
+    assertU(adoc(doc4));
+    assertU(commit());
+    String[] doc5 = {"id","6", "sort_i","11"};
+    assertU(adoc(doc5));
+    assertU(commit());
+
+
+    ModifiableSolrParams params = new ModifiableSolrParams();
+
+    params.add("q", "*:*");
+    params.add("fq", "{!count}");
+
+    assertQ(req(params), " //lst[@name='analytics']/int[@name='mycount'][.=6]");
+
+    params = new ModifiableSolrParams();
+
+    params.add("q", "id:(3 4)");
+    params.add("fq", "{!count}");
+
+    assertQ(req(params), " //lst[@name='analytics']/int[@name='mycount'][.=2]");
+
+  }
+}

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestAnalyticsQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestAnalyticsQParserPlugin.java?rev=1601664&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestAnalyticsQParserPlugin.java
(added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestAnalyticsQParserPlugin.java
Tue Jun 10 15:08:48 2014
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.search;
+
+import org.apache.lucene.search.LeafCollector;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.handler.component.ResponseBuilder;
+import org.apache.solr.handler.component.ShardRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.handler.component.MergeStrategy;
+import org.apache.solr.handler.component.ShardResponse;
+
+import org.junit.Ignore;
+import java.io.IOException;
+
+@Ignore
+public class TestAnalyticsQParserPlugin extends QParserPlugin {
+
+
+  public void init(NamedList params) {
+
+  }
+
+  public QParser createParser(String query, SolrParams localParams, SolrParams params, SolrQueryRequest
req) {
+    return new TestAnalyticsQueryParser(query, localParams, params, req);
+  }
+
+  class TestAnalyticsQueryParser extends QParser {
+
+    public TestAnalyticsQueryParser(String query, SolrParams localParams, SolrParams params,
SolrQueryRequest req) {
+      super(query, localParams, params, req);
+    }
+
+    public Query parse() throws SyntaxError {
+      return new TestAnalyticsQuery(new TestAnalyticsMergeStrategy());
+    }
+  }
+
+  class TestAnalyticsQuery extends AnalyticsQuery {
+
+    public TestAnalyticsQuery(MergeStrategy mergeStrategy) {
+      super(mergeStrategy);
+    }
+
+    public DelegatingCollector getAnalyticsCollector(ResponseBuilder rb, IndexSearcher searcher)
{
+      return new TestAnalyticsCollector(rb);
+    }
+  }
+
+  class TestAnalyticsCollector extends DelegatingCollector {
+    ResponseBuilder rb;
+    int count;
+
+    public TestAnalyticsCollector(ResponseBuilder rb) {
+      this.rb = rb;
+    }
+
+    public void collect(int doc) throws IOException {
+      ++count;
+      leafDelegate.collect(doc);
+    }
+
+    public void finish() throws IOException {
+      NamedList analytics = new NamedList();
+      rb.rsp.add("analytics", analytics);
+      analytics.add("mycount", count);
+      if(this.delegate instanceof DelegatingCollector) {
+        ((DelegatingCollector)this.delegate).finish();
+      }
+    }
+  }
+
+  class TestAnalyticsMergeStrategy implements MergeStrategy {
+
+    public boolean mergesIds() {
+      return false;
+    }
+
+    public boolean handlesMergeFields() {
+      return false;
+    }
+
+    public int getCost() {
+      return 100;
+    }
+
+    public void  handleMergeFields(ResponseBuilder rb, SolrIndexSearcher searcher) {
+    }
+
+    public void merge(ResponseBuilder rb, ShardRequest shardRequest) {
+      int count = 0;
+      NamedList merged = new NamedList();
+
+      for(ShardResponse shardResponse : shardRequest.responses) {
+        NamedList response = shardResponse.getSolrResponse().getResponse();
+        NamedList analytics = (NamedList)response.get("analytics");
+        Integer c = (Integer)analytics.get("mycount");
+        count += c.intValue();
+      }
+
+      merged.add("mycount", count);
+      rb.rsp.add("analytics", merged);
+    }
+  }
+}



Mime
View raw message