You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by is...@apache.org on 2017/03/19 15:57:36 UTC
[02/12] lucene-solr:jira/solr-6736: Merge master into jira/solr-6736
branch
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/search/TestMultiWordSynonyms.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestMultiWordSynonyms.java b/solr/core/src/test/org/apache/solr/search/TestMultiWordSynonyms.java
new file mode 100644
index 0000000..ecc80c3
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/search/TestMultiWordSynonyms.java
@@ -0,0 +1,100 @@
+/*
+ * 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 java.util.Arrays;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestMultiWordSynonyms extends SolrTestCaseJ4 {
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ initCore("solrconfig.xml", "schema-multiword-synonyms.xml");
+ index();
+ }
+
+ private static void index() throws Exception {
+ assertU(adoc("id","1", "text","USA Today"));
+ assertU(adoc("id","2", "text","A dynamic US economy"));
+ assertU(adoc("id","3", "text","The United States of America's 50 states"));
+ assertU(adoc("id","4", "text","Party in the U.S.A."));
+ assertU(adoc("id","5", "text","These United States"));
+
+ assertU(adoc("id","6", "text","America United of States"));
+ assertU(adoc("id","7", "text","States United"));
+
+ assertU(commit());
+ }
+
+ @Test
+ public void testNonPhrase() throws Exception {
+ // Don't split on whitespace (sow=false)
+ for (String q : Arrays.asList("US", "U.S.", "USA", "U.S.A.", "United States", "United States of America")) {
+ for (String defType : Arrays.asList("lucene", "edismax")) {
+ assertJQ(req("q", q,
+ "defType", defType,
+ "df", "text",
+ "sow", "false")
+ , "/response/numFound==7"
+ );
+ }
+ }
+
+ // Split on whitespace (sow=true)
+ for (String q : Arrays.asList("US", "U.S.", "USA", "U.S.A.")) {
+ for (String defType : Arrays.asList("lucene", "edismax")) {
+ assertJQ(req("q", q,
+ "defType", defType,
+ "df", "text",
+ "sow", "true")
+ , "/response/numFound==7"
+ );
+ }
+ }
+ for (String q : Arrays.asList("United States", "United States of America")) {
+ for (String defType : Arrays.asList("lucene", "edismax")) {
+ assertJQ(req("q", q,
+ "defType", defType,
+ "df", "text",
+ "sow", "true")
+ , "/response/numFound==4"
+ );
+ }
+ }
+ }
+
+ @Test
+ public void testPhrase() throws Exception {
+ for (String q : Arrays.asList
+ ("\"US\"", "\"U.S.\"", "\"USA\"", "\"U.S.A.\"", "\"United States\"", "\"United States of America\"")) {
+ for (String defType : Arrays.asList("lucene", "edismax")) {
+ for (String sow : Arrays.asList("true", "false")) {
+ assertJQ(req("q", q,
+ "defType", defType,
+ "df", "text",
+ "sow", sow)
+ , "/response/numFound==5"
+ );
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java b/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java
index 2fe3740..8cd96ae 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java
@@ -19,7 +19,6 @@ package org.apache.solr.search;
import java.text.ParseException;
import java.util.Arrays;
-import com.carrotsearch.randomizedtesting.RandomizedTest;
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.distance.DistanceUtils;
@@ -43,16 +42,18 @@ import org.junit.Test;
*/
public class TestSolr4Spatial extends SolrTestCaseJ4 {
- private String fieldName;
+ private final String fieldName;
+ private final boolean canCalcDistance;
public TestSolr4Spatial(String fieldName) {
this.fieldName = fieldName;
+ this.canCalcDistance = !fieldName.equals("llp_idx");
}
@ParametersFactory
public static Iterable<Object[]> parameters() {
return Arrays.asList(new Object[][]{
- {"srpt_geohash"}, {"srpt_quad"}, {"srpt_packedquad"}, {"stqpt_geohash"}, {"pointvector"}, {"bbox"}
+ {"llp"}, {"llp_idx"}, {"llp_dv"}, {"srpt_geohash"}, {"srpt_quad"}, {"srpt_packedquad"}, {"stqpt_geohash"}, {"pointvector"}, {"bbox"}
});
}
@@ -105,6 +106,10 @@ public class TestSolr4Spatial extends SolrTestCaseJ4 {
assertU(adoc("id", "11", fieldName, "89.9,-130"));
assertU(adoc("id", "12", fieldName, "-89.9,50"));
assertU(adoc("id", "13", fieldName, "-89.9,-130"));
+ if (random().nextBoolean()) {
+ assertU(commit());
+ }
+ assertU(adoc("id", "99"));//blank
assertU(commit());
}
@@ -192,7 +197,7 @@ public class TestSolr4Spatial extends SolrTestCaseJ4 {
//Test using the Lucene spatial syntax
{
//never actually need the score but lets test
- String score = new String[]{null, "none","distance","recipDistance"}[random().nextInt(4)];
+ String score = randomScoreMode();
double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
Point point = SpatialUtils.parsePoint(ptStr, SpatialContext.GEO);
@@ -225,6 +230,10 @@ public class TestSolr4Spatial extends SolrTestCaseJ4 {
}
+ private String randomScoreMode() {
+ return canCalcDistance ? new String[]{null, "none","distance","recipDistance"}[random().nextInt(4)] : "none";
+ }
+
@Test
public void testRangeSyntax() {
setupDocs();
@@ -232,10 +241,10 @@ public class TestSolr4Spatial extends SolrTestCaseJ4 {
int docId = 1;
int count = 1;
- String score = random().nextBoolean() ? "none" : "distance";//never actually need the score but lets test
+ String score = randomScoreMode();//never actually need the score but lets test
assertQ(req(
"fl", "id", "q","*:*", "rows", "1000", // testing quotes in range too
- "fq", "{! score="+score+" df="+fieldName+"}[32,-80 TO \"33 , -79\"]"),//lower-left to upper-right
+ "fq", "{! "+(score==null?"":" score="+score)+" df="+fieldName+"}[32,-80 TO \"33 , -79\"]"),//lower-left to upper-right
"//result/doc/*[@name='id'][.='" + docId + "']",
"*[count(//doc)=" + count + "]");
@@ -243,13 +252,46 @@ public class TestSolr4Spatial extends SolrTestCaseJ4 {
@Test
public void testSort() throws Exception {
+ assumeTrue("dist sorting not supported on field " + fieldName, canCalcDistance);
assertU(adoc("id", "100", fieldName, "1,2"));
assertU(adoc("id", "101", fieldName, "4,-1"));
- assertU(adoc("id", "999", fieldName, "70,70"));//far away from these queries
+ if (random().nextBoolean()) {
+ assertU(commit()); // new segment
+ }
+ if (random().nextBoolean()) {
+ assertU(adoc("id", "999", fieldName, "70,70"));//far away from these queries; we filter it out
+ } else {
+ assertU(adoc("id", "999")); // no data
+ }
assertU(commit());
- //test absence of score=distance means it doesn't score
+ // geodist asc
+ assertJQ(req(
+ "q", radiusQuery(3, 4, 9, null, null),
+ "fl","id",
+ "sort","geodist() asc",
+ "sfield", fieldName, "pt", "3,4")
+ , 1e-3
+ , "/response/docs/[0]/id=='100'"
+ , "/response/docs/[1]/id=='101'"
+ );
+ // geodist desc (simply reverse the assertions)
+ assertJQ(req(
+ "q", radiusQuery(3, 4, 9, null, null),
+ "fl","id",
+ "sort","geodist() desc", // DESC
+ "sfield", fieldName, "pt", "3,4")
+ , 1e-3
+ , "/response/docs/[0]/id=='101'" // FLIPPED
+ , "/response/docs/[1]/id=='100'" // FLIPPED
+ );
+
+ //
+ // NOTE: the rest work via the score of the spatial query. Generally, you should use geodist() instead.
+ //
+
+ //test absence of score=distance means it doesn't score
assertJQ(req(
"q", radiusQuery(3, 4, 9, null, null),
"fl","id,score")
@@ -345,7 +387,8 @@ public class TestSolr4Spatial extends SolrTestCaseJ4 {
@Test
public void testSortMultiVal() throws Exception {
- RandomizedTest.assumeFalse("Multivalue not supported for this field",
+ assumeTrue("dist sorting not supported on field " + fieldName, canCalcDistance);
+ assumeFalse("Multivalue not supported for this field",
fieldName.equals("pointvector") || fieldName.equals("bbox"));
assertU(adoc("id", "100", fieldName, "1,2"));//1 point
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheMBean.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheMBean.java b/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheMBean.java
index 35bdec6..d11c919 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheMBean.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheMBean.java
@@ -68,7 +68,7 @@ public class TestSolrFieldCacheMBean extends SolrTestCaseJ4 {
private void assertEntryListIncluded(boolean checkJmx) {
SolrFieldCacheMBean mbean = new SolrFieldCacheMBean();
NamedList stats = checkJmx ? mbean.getStatisticsForJmx() : mbean.getStatistics();
- assert(new Integer(stats.get("entries_count").toString()) > 0);
+ assert(Integer.parseInt(stats.get("entries_count").toString()) > 0);
assertNotNull(stats.get("total_size"));
assertNotNull(stats.get("entry#0"));
}
@@ -76,7 +76,7 @@ public class TestSolrFieldCacheMBean extends SolrTestCaseJ4 {
private void assertEntryListNotIncluded(boolean checkJmx) {
SolrFieldCacheMBean mbean = new SolrFieldCacheMBean();
NamedList stats = checkJmx ? mbean.getStatisticsForJmx() : mbean.getStatistics();
- assert(new Integer(stats.get("entries_count").toString()) > 0);
+ assert(Integer.parseInt(stats.get("entries_count").toString()) > 0);
assertNull(stats.get("total_size"));
assertNull(stats.get("entry#0"));
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/search/TestSolrQueryParser.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolrQueryParser.java b/solr/core/src/test/org/apache/solr/search/TestSolrQueryParser.java
index 8195c05..92bd6c0 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolrQueryParser.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolrQueryParser.java
@@ -16,7 +16,12 @@
*/
package org.apache.solr.search;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Random;
import org.apache.lucene.search.BooleanClause;
@@ -28,12 +33,15 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.core.SolrInfoMBean;
import org.apache.solr.parser.QueryParser;
import org.apache.solr.query.FilterQuery;
import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.schema.TextField;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.noggit.ObjectBuilder;
public class TestSolrQueryParser extends SolrTestCaseJ4 {
@@ -57,6 +65,8 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
assertU(adoc("id", "12", "eee_s", "X"));
assertU(adoc("id", "13", "eee_s", "'balance'", "rrr_s", "/leading_slash"));
+ assertU(adoc("id", "20", "syn", "wifi ATM"));
+
assertU(commit());
}
@@ -208,86 +218,105 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
QParser qParser;
Query q,qq;
- // relevance query should not be a filter
- qParser = QParser.getParser("foo_s:(a b c)", req);
- q = qParser.getQuery();
- assertEquals(3, ((BooleanQuery)q).clauses().size());
-
- // small filter query should still use BooleanQuery
- if (QueryParser.TERMS_QUERY_THRESHOLD > 3) {
+ Map<String, String> sowFalseParamsMap = new HashMap<>();
+ sowFalseParamsMap.put("sow", "false");
+ Map<String, String> sowTrueParamsMap = new HashMap<>();
+ sowTrueParamsMap.put("sow", "true");
+ List<MapSolrParams> paramMaps = Arrays.asList
+ (new MapSolrParams(Collections.emptyMap()), // no sow param (i.e. the default sow value)
+ new MapSolrParams(sowFalseParamsMap),
+ new MapSolrParams(sowTrueParamsMap));
+
+ for (MapSolrParams params : paramMaps) {
+ // relevance query should not be a filter
qParser = QParser.getParser("foo_s:(a b c)", req);
- qParser.setIsFilter(true); // this may change in the future
+ qParser.setParams(params);
q = qParser.getQuery();
assertEquals(3, ((BooleanQuery) q).clauses().size());
- }
- // large relevancy query should use BooleanQuery
- // TODO: we may decide that string fields shouldn't have relevance in the future... change to a text field w/o a stop filter if so
- qParser = QParser.getParser("foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z)", req);
- q = qParser.getQuery();
- assertEquals(26, ((BooleanQuery)q).clauses().size());
+ // small filter query should still use BooleanQuery
+ if (QueryParser.TERMS_QUERY_THRESHOLD > 3) {
+ qParser = QParser.getParser("foo_s:(a b c)", req);
+ qParser.setParams(params);
+ qParser.setIsFilter(true); // this may change in the future
+ q = qParser.getQuery();
+ assertEquals(3, ((BooleanQuery) q).clauses().size());
+ }
- // large filter query should use TermsQuery
- qParser = QParser.getParser("foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z)", req);
- qParser.setIsFilter(true); // this may change in the future
- q = qParser.getQuery();
- assertEquals(26, ((TermInSetQuery)q).getTermData().size());
+ // large relevancy query should use BooleanQuery
+ // TODO: we may decide that string fields shouldn't have relevance in the future... change to a text field w/o a stop filter if so
+ qParser = QParser.getParser("foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z)", req);
+ qParser.setParams(params);
+ q = qParser.getQuery();
+ assertEquals(26, ((BooleanQuery)q).clauses().size());
- // large numeric filter query should use TermsQuery (for trie fields)
- qParser = QParser.getParser("foo_ti:(1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11)", req);
- qParser.setIsFilter(true); // this may change in the future
- q = qParser.getQuery();
- assertEquals(20, ((TermInSetQuery)q).getTermData().size());
-
- // for point fields large filter query should use PointInSetQuery
- qParser = QParser.getParser("foo_pi:(1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11)", req);
- qParser.setIsFilter(true); // this may change in the future
- q = qParser.getQuery();
- assertTrue(q instanceof PointInSetQuery);
- assertEquals(20, ((PointInSetQuery)q).getPackedPoints().size());
+ // large filter query should use TermsQuery
+ qParser = QParser.getParser("foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z)", req);
+ qParser.setIsFilter(true); // this may change in the future
+ qParser.setParams(params);
+ q = qParser.getQuery();
+ assertEquals(26, ((TermInSetQuery)q).getTermData().size());
- // a filter() clause inside a relevancy query should be able to use a TermsQuery
- qParser = QParser.getParser("foo_s:aaa filter(foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z))", req);
- q = qParser.getQuery();
- assertEquals(2, ((BooleanQuery)q).clauses().size());
- qq = ((BooleanQuery)q).clauses().get(0).getQuery();
- if (qq instanceof TermQuery) {
- qq = ((BooleanQuery)q).clauses().get(1).getQuery();
- }
+ // large numeric filter query should use TermsQuery (for trie fields)
+ qParser = QParser.getParser("foo_ti:(1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11)", req);
+ qParser.setIsFilter(true); // this may change in the future
+ qParser.setParams(params);
+ q = qParser.getQuery();
+ assertEquals(20, ((TermInSetQuery)q).getTermData().size());
- if (qq instanceof FilterQuery) {
- qq = ((FilterQuery)qq).getQuery();
- }
+ // for point fields large filter query should use PointInSetQuery
+ qParser = QParser.getParser("foo_pi:(1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11)", req);
+ qParser.setIsFilter(true); // this may change in the future
+ qParser.setParams(params);
+ q = qParser.getQuery();
+ assertTrue(q instanceof PointInSetQuery);
+ assertEquals(20, ((PointInSetQuery)q).getPackedPoints().size());
- assertEquals(26, ((TermInSetQuery)qq).getTermData().size());
+ // a filter() clause inside a relevancy query should be able to use a TermsQuery
+ qParser = QParser.getParser("foo_s:aaa filter(foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z))", req);
+ qParser.setParams(params);
+ q = qParser.getQuery();
+ assertEquals(2, ((BooleanQuery)q).clauses().size());
+ qq = ((BooleanQuery)q).clauses().get(0).getQuery();
+ if (qq instanceof TermQuery) {
+ qq = ((BooleanQuery)q).clauses().get(1).getQuery();
+ }
- // test mixed boolean query, including quotes (which shouldn't matter)
- qParser = QParser.getParser("foo_s:(a +aaa b -bbb c d e f bar_s:(qqq www) g h i j k l m n o p q r s t u v w x y z)", req);
- qParser.setIsFilter(true); // this may change in the future
- q = qParser.getQuery();
- assertEquals(4, ((BooleanQuery)q).clauses().size());
- qq = null;
- for (BooleanClause clause : ((BooleanQuery)q).clauses()) {
- qq = clause.getQuery();
- if (qq instanceof TermInSetQuery) break;
- }
- assertEquals(26, ((TermInSetQuery)qq).getTermData().size());
+ if (qq instanceof FilterQuery) {
+ qq = ((FilterQuery)qq).getQuery();
+ }
- // test terms queries of two different fields (LUCENE-7637 changed to require all terms be in the same field)
- StringBuilder sb = new StringBuilder();
- for (int i=0; i<17; i++) {
- char letter = (char)('a'+i);
- sb.append("foo_s:" + letter + " bar_s:" + letter + " ");
- }
- qParser = QParser.getParser(sb.toString(), req);
- qParser.setIsFilter(true); // this may change in the future
- q = qParser.getQuery();
- assertEquals(2, ((BooleanQuery)q).clauses().size());
- for (BooleanClause clause : ((BooleanQuery)q).clauses()) {
- qq = clause.getQuery();
- assertEquals(17, ((TermInSetQuery)qq).getTermData().size());
- }
+ assertEquals(26, ((TermInSetQuery) qq).getTermData().size());
+
+ // test mixed boolean query, including quotes (which shouldn't matter)
+ qParser = QParser.getParser("foo_s:(a +aaa b -bbb c d e f bar_s:(qqq www) g h i j k l m n o p q r s t u v w x y z)", req);
+ qParser.setIsFilter(true); // this may change in the future
+ qParser.setParams(params);
+ q = qParser.getQuery();
+ assertEquals(4, ((BooleanQuery)q).clauses().size());
+ qq = null;
+ for (BooleanClause clause : ((BooleanQuery)q).clauses()) {
+ qq = clause.getQuery();
+ if (qq instanceof TermInSetQuery) break;
+ }
+ assertEquals(26, ((TermInSetQuery)qq).getTermData().size());
+ // test terms queries of two different fields (LUCENE-7637 changed to require all terms be in the same field)
+ StringBuilder sb = new StringBuilder();
+ for (int i=0; i<17; i++) {
+ char letter = (char)('a'+i);
+ sb.append("foo_s:" + letter + " bar_s:" + letter + " ");
+ }
+ qParser = QParser.getParser(sb.toString(), req);
+ qParser.setIsFilter(true); // this may change in the future
+ qParser.setParams(params);
+ q = qParser.getQuery();
+ assertEquals(2, ((BooleanQuery)q).clauses().size());
+ for (BooleanClause clause : ((BooleanQuery)q).clauses()) {
+ qq = clause.getQuery();
+ assertEquals(17, ((TermInSetQuery)qq).getTermData().size());
+ }
+ }
req.close();
}
@@ -306,6 +335,10 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
// This will still fail when used as the main query, but will pass in a filter query since TermsQuery can be used.
assertJQ(req("q","*:*", "fq", q)
,"/response/numFound==6");
+ assertJQ(req("q","*:*", "fq", q, "sow", "false")
+ ,"/response/numFound==6");
+ assertJQ(req("q","*:*", "fq", q, "sow", "true")
+ ,"/response/numFound==6");
}
@Test
@@ -540,4 +573,400 @@ public class TestSolrQueryParser extends SolrTestCaseJ4 {
req.close();
}
+ // LUCENE-7533
+ public void testSplitOnWhitespace_with_autoGeneratePhraseQueries() throws Exception {
+ assertTrue(((TextField)h.getCore().getLatestSchema().getField("text").getType()).getAutoGeneratePhraseQueries());
+
+ try (SolrQueryRequest req = req()) {
+ final QParser qparser = QParser.getParser("{!lucene sow=false qf=text}blah blah", req);
+ expectThrows(QueryParserConfigurationException.class, qparser::getQuery);
+ }
+ }
+
+ @Test
+ public void testSplitOnWhitespace_Basic() throws Exception {
+ // The "syn" field has synonyms loaded from synonyms.txt
+
+ assertJQ(req("df", "syn", "q", "wifi", "sow", "true") // retrieve the single document containing literal "wifi"
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+
+ assertJQ(req("df", "syn", "q", "wi fi", "sow", "false") // trigger the "wi fi => wifi" synonym
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+
+ assertJQ(req("df", "syn", "q", "wi fi", "sow", "true")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi") // default sow=true
+ , "/response/numFound==0"
+ );
+
+ assertJQ(req("df", "syn", "q", "{!lucene sow=false}wi fi")
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=true}wi fi")
+ , "/response/numFound==0"
+ );
+
+ assertJQ(req("df", "syn", "q", "{!lucene}wi fi") // default sow=true
+ , "/response/numFound==0"
+ );
+ }
+
+ public void testSplitOnWhitespace_Comments() throws Exception {
+ // The "syn" field has synonyms loaded from synonyms.txt
+
+ assertJQ(req("df", "syn", "q", "wifi", "sow", "true") // retrieve the single document containing literal "wifi"
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi", "sow", "false") // trigger the "wi fi => wifi" synonym
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "wi /* foo */ fi", "sow", "false") // trigger the "wi fi => wifi" synonym
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "wi /* foo */ /* bar */ fi", "sow", "false") // trigger the "wi fi => wifi" synonym
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", " /* foo */ wi fi /* bar */", "sow", "false") // trigger the "wi fi => wifi" synonym
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", " /* foo */ wi /* bar */ fi /* baz */", "sow", "false") // trigger the "wi fi => wifi" synonym
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+
+ assertJQ(req("df", "syn", "q", "wi fi", "sow", "true")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi /* foo */ fi", "sow", "true")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi /* foo */ /* bar */ fi", "sow", "true")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "/* foo */ wi fi /* bar */", "sow", "true")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "/* foo */ wi /* bar */ fi /* baz */", "sow", "true")
+ , "/response/numFound==0"
+ );
+
+ assertJQ(req("df", "syn", "q", "wi fi") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi /* foo */ fi") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi /* foo */ /* bar */ fi") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "/* foo */ wi fi /* bar */") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "/* foo */ wi /* bar */ fi /* baz */") // default sow=true
+ , "/response/numFound==0"
+ );
+
+
+ assertJQ(req("df", "syn", "q", "{!lucene sow=false}wi fi")
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=false}wi /* foo */ fi")
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=false}wi /* foo */ /* bar */ fi")
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=false}/* foo */ wi fi /* bar */")
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=false}/* foo */ wi /* bar */ fi /* baz */")
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+
+ assertJQ(req("df", "syn", "q", "{!lucene sow=true}wi fi")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=true}wi /* foo */ fi")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=true}wi /* foo */ /* bar */ fi")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=true}/* foo */ wi fi /* bar */")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene sow=true}/* foo */ wi /* bar */ fi /* baz */")
+ , "/response/numFound==0"
+ );
+
+ assertJQ(req("df", "syn", "q", "{!lucene}wi fi") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene}wi /* foo */ fi") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene}wi /* foo */ /* bar */ fi") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene}/* foo */ wi fi /* bar */") // default sow=true
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "{!lucene}/* foo */ wi /* bar */ fi /* baz */") // default sow=true
+ , "/response/numFound==0"
+ );
+ }
+
+ public void testOperatorsAndMultiWordSynonyms() throws Exception {
+ // The "syn" field has synonyms loaded from synonyms.txt
+
+ assertJQ(req("df", "syn", "q", "wifi", "sow", "true") // retrieve the single document containing literal "wifi"
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi", "sow", "false") // trigger the "wi fi => wifi" synonym
+ , "/response/numFound==1"
+ , "/response/docs/[0]/id=='20'"
+ );
+
+ assertJQ(req("df", "syn", "q", "+wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "-wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "!wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi* fi", "sow", "false") // matches because wi* matches wifi
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "w? fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi~1 fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi^2 fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi^=2 fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi +fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi -fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi !fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi*", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi?", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi~1", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi^2", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi^=2", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "syn:wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi syn:fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "NOT wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi NOT fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+
+ assertJQ(req("df", "syn", "q", "wi fi AND ATM", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "ATM AND wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi && ATM", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "ATM && wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "(wi fi) AND ATM", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "ATM AND (wi fi)", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "(wi fi) && ATM", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "ATM && (wi fi)", "sow", "false")
+ , "/response/numFound==1"
+ );
+
+ assertJQ(req("df", "syn", "q", "wi fi OR NotThereAtAll", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "NotThereAtAll OR wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi || NotThereAtAll", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "NotThereAtAll || wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "(wi fi) OR NotThereAtAll", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "NotThereAtAll OR (wi fi)", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "(wi fi) || NotThereAtAll", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "NotThereAtAll || (wi fi)", "sow", "false")
+ , "/response/numFound==1"
+ );
+
+ assertJQ(req("df", "syn", "q", "\"wi\" fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi \"fi\"", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "(wi) fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi (fi)", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "/wi/ fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi /fi/", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "(wi fi)", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "+(wi fi)", "sow", "false")
+ , "/response/numFound==1"
+ );
+
+ Map all = (Map)ObjectBuilder.fromJSON(h.query(req("q", "*:*", "rows", "0", "wt", "json")));
+ int totalDocs = Integer.parseInt(((Map)all.get("response")).get("numFound").toString());
+ int allDocsExceptOne = totalDocs - 1;
+
+ assertJQ(req("df", "syn", "q", "-(wi fi)", "sow", "false")
+ , "/response/numFound==" + allDocsExceptOne // one doc contains "wifi" in the syn field
+ );
+ assertJQ(req("df", "syn", "q", "!(wi fi)", "sow", "false")
+ , "/response/numFound==" + allDocsExceptOne // one doc contains "wifi" in the syn field
+ );
+ assertJQ(req("df", "syn", "q", "NOT (wi fi)", "sow", "false")
+ , "/response/numFound==" + allDocsExceptOne // one doc contains "wifi" in the syn field
+ );
+ assertJQ(req("df", "syn", "q", "(wi fi)^2", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "(wi fi)^=2", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "syn:(wi fi)", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "+ATM wi fi", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "-ATM wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "-NotThereAtAll wi fi", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "!ATM wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "!NotThereAtAll wi fi", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "NOT ATM wi fi", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "NOT NotThereAtAll wi fi", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "AT* wi fi", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "AT? wi fi", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "\"ATM\" wi fi", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi +ATM", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi -ATM", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi -NotThereAtAll", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi !ATM", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi !NotThereAtAll", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi NOT ATM", "sow", "false")
+ , "/response/numFound==0"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi NOT NotThereAtAll", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi AT*", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi AT?", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "wi fi \"ATM\"", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "\"wi fi\"~2", "sow", "false")
+ , "/response/numFound==1"
+ );
+ assertJQ(req("df", "syn", "q", "syn:\"wi fi\"", "sow", "false")
+ , "/response/numFound==1"
+ );
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacetRefinement.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacetRefinement.java b/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacetRefinement.java
index a8f8ff2..f23ae8c 100644
--- a/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacetRefinement.java
+++ b/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacetRefinement.java
@@ -18,9 +18,12 @@
package org.apache.solr.search.facet;
import java.io.IOException;
+import java.util.List;
import org.apache.solr.JSONTestUtil;
import org.apache.solr.SolrTestCaseHS;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.request.SolrQueryRequest;
import org.junit.AfterClass;
@@ -209,6 +212,97 @@ public class TestJsonFacetRefinement extends SolrTestCaseHS {
}
+ @Test
+ public void testBasicRefinement() throws Exception {
+ initServers();
+ Client client = servers.getClient(random().nextInt());
+ client.queryDefaults().set( "shards", servers.getShards(), "debugQuery", Boolean.toString(random().nextBoolean()) );
+
+ List<SolrClient> clients = client.getClientProvider().all();
+ assertTrue(clients.size() >= 3);
+
+ client.deleteByQuery("*:*", null);
+
+ ModifiableSolrParams p = params("cat_s", "cat_s", "num_d", "num_d");
+ String cat_s = p.get("cat_s");
+ String num_d = p.get("num_d");
+
+ clients.get(0).add( sdoc("id", "01", cat_s, "A", num_d, -1) ); // A wins count tie
+ clients.get(0).add( sdoc("id", "02", cat_s, "B", num_d, 3) );
+
+ clients.get(1).add( sdoc("id", "11", cat_s, "B", num_d, -5) ); // B highest count
+ clients.get(1).add( sdoc("id", "12", cat_s, "B", num_d, -11) );
+ clients.get(1).add( sdoc("id", "13", cat_s, "A", num_d, 7) );
+
+ clients.get(2).add( sdoc("id", "21", cat_s, "A", num_d, 17) ); // A highest count
+ clients.get(2).add( sdoc("id", "22", cat_s, "A", num_d, -19) );
+ clients.get(2).add( sdoc("id", "23", cat_s, "B", num_d, 11) );
+
+ client.commit();
+
+ // Shard responses should be A=1, B=2, A=2, merged should be "A=3, B=2"
+ // One shard will have _facet_={"refine":{"cat0":{"_l":["A"]}}} on the second phase
+
+ /****
+ // fake a refinement request... good for development/debugging
+ assertJQ(clients.get(1),
+ params(p, "q", "*:*", "_facet_","{refine:{cat0:{_l:[A]}}}", "isShard","true", "distrib","false", "shards.purpose","2097216", "ids","11,12,13",
+ "json.facet", "{" +
+ "cat0:{type:terms, field:cat_s, sort:'count desc', limit:1, overrequest:0, refine:true}" +
+ "}"
+ )
+ , "facets=={foo:555}"
+ );
+ ****/
+
+ client.testJQ(params(p, "q", "*:*",
+ "json.facet", "{" +
+ "cat0:{type:terms, field:${cat_s}, sort:'count desc', limit:1, overrequest:0, refine:false}" +
+ "}"
+ )
+ , "facets=={ count:8" +
+ ", cat0:{ buckets:[ {val:A,count:3} ] }" + // w/o overrequest and refinement, count is lower than it should be (we don't see the A from the middle shard)
+ "}"
+ );
+
+ client.testJQ(params(p, "q", "*:*",
+ "json.facet", "{" +
+ "cat0:{type:terms, field:${cat_s}, sort:'count desc', limit:1, overrequest:0, refine:true}" +
+ "}"
+ )
+ , "facets=={ count:8" +
+ ", cat0:{ buckets:[ {val:A,count:4} ] }" + // w/o overrequest, we need refining to get the correct count.
+ "}"
+ );
+
+ // test that basic stats work for refinement
+ client.testJQ(params(p, "q", "*:*",
+ "json.facet", "{" +
+ "cat0:{type:terms, field:${cat_s}, sort:'count desc', limit:1, overrequest:0, refine:true, facet:{ stat1:'sum(${num_d})'} }" +
+ "}"
+ )
+ , "facets=={ count:8" +
+ ", cat0:{ buckets:[ {val:A,count:4, stat1:4.0} ] }" +
+ "}"
+ );
+
+ // test sorting buckets by a different stat
+ client.testJQ(params(p, "q", "*:*",
+ "json.facet", "{" +
+ " cat0:{type:terms, field:${cat_s}, sort:'min1 asc', limit:1, overrequest:0, refine:false, facet:{ min1:'min(${num_d})'} }" +
+ ",cat1:{type:terms, field:${cat_s}, sort:'min1 asc', limit:1, overrequest:0, refine:true, facet:{ min1:'min(${num_d})'} }" +
+ ",sum1:'sum(num_d)'" + // make sure that root bucket stats aren't affected by refinement
+ "}"
+ )
+ , "facets=={ count:8" +
+ ", cat0:{ buckets:[ {val:A,count:3, min1:-19.0} ] }" + // B wins in shard2, so we're missing the "A" count for that shar w/o refinement.
+ ", cat1:{ buckets:[ {val:A,count:4, min1:-19.0} ] }" + // with refinement, we get the right count
+ ", sum1:2.0" +
+ "}"
+ );
+
+
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java b/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java
index e3a8d7b..f502f24 100644
--- a/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java
+++ b/solr/core/src/test/org/apache/solr/search/mlt/CloudMLTQParserTest.java
@@ -102,7 +102,7 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
int[] actualIds = new int[10];
int i = 0;
for (SolrDocument solrDocument : solrDocuments) {
- actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+ actualIds[i++] = Integer.parseInt(String.valueOf(solrDocument.getFieldValue("id")));
}
assertArrayEquals(expectedIds, actualIds);
@@ -117,7 +117,7 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
int[] actualIds = new int[solrDocuments.size()];
int i = 0;
for (SolrDocument solrDocument : solrDocuments) {
- actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+ actualIds[i++] = Integer.parseInt(String.valueOf(solrDocument.getFieldValue("id")));
}
assertArrayEquals(expectedIds, actualIds);
@@ -127,7 +127,7 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
actualIds = new int[solrDocuments.size()];
i = 0;
for (SolrDocument solrDocument : solrDocuments) {
- actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+ actualIds[i++] = Integer.parseInt(String.valueOf(solrDocument.getFieldValue("id")));
}
System.out.println("DEBUG ACTUAL IDS 1: " + Arrays.toString(actualIds));
assertArrayEquals(expectedIds, actualIds);
@@ -138,7 +138,7 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
actualIds = new int[solrDocuments.size()];
i = 0;
for (SolrDocument solrDocument : solrDocuments) {
- actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+ actualIds[i++] = Integer.parseInt(String.valueOf(solrDocument.getFieldValue("id")));
}
System.out.println("DEBUG ACTUAL IDS 2: " + Arrays.toString(actualIds));
assertArrayEquals(expectedIds, actualIds);
@@ -154,7 +154,7 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
int[] actualIds = new int[solrDocuments.size()];
int i = 0;
for (SolrDocument solrDocument : solrDocuments) {
- actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+ actualIds[i++] = Integer.parseInt(String.valueOf(solrDocument.getFieldValue("id")));
}
assertArrayEquals(expectedIds, actualIds);
@@ -184,7 +184,7 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
int[] actualIds = new int[solrDocuments.size()];
int i = 0;
for (SolrDocument solrDocument : solrDocuments) {
- actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+ actualIds[i++] = Integer.parseInt(String.valueOf(solrDocument.getFieldValue("id")));
}
assertArrayEquals(expectedIds, actualIds);
@@ -236,7 +236,7 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
int i = 0;
StringBuilder sb = new StringBuilder();
for (SolrDocument solrDocument : solrDocuments) {
- actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
+ actualIds[i++] = Integer.parseInt(String.valueOf(solrDocument.getFieldValue("id")));
sb.append(actualIds[i-1]).append(", ");
}
assertArrayEquals(expectedIds, actualIds);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java b/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
index 2816354..462241a 100644
--- a/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
@@ -119,7 +119,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
String delsQName = PREFIX + "deletesByQuery";
String cumulativeDelsQName = PREFIX + "cumulativeDeletesByQuery";
long commits = ((Meter) metrics.get(commitsName)).getCount();
- long adds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+ long adds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
long cumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
long cumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
long cumulativeDelsQ = ((Meter) metrics.get(cumulativeDelsQName)).getCount();
@@ -137,7 +137,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
assertQ(req("q","id:5"), "//*[@numFound='0']");
assertQ(req("q","id:6"), "//*[@numFound='0']");
- long newAdds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+ long newAdds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
long newCumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
assertEquals("new adds", 2, newAdds - adds);
assertEquals("new cumulative adds", 2, newCumulativeAdds - cumulativeAdds);
@@ -147,7 +147,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
long newCommits = ((Meter) metrics.get(commitsName)).getCount();
assertEquals("new commits", 1, newCommits - commits);
- newAdds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+ newAdds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
newCumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
// adds should be reset to 0 after commit
assertEquals("new adds after commit", 0, newAdds);
@@ -161,7 +161,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
// now delete one
assertU(delI("5"));
- long newDelsI = ((Gauge<Long>) metrics.get(delsIName)).getValue();
+ long newDelsI = ((Gauge<Number>) metrics.get(delsIName)).getValue().longValue();
long newCumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
assertEquals("new delsI", 1, newDelsI);
assertEquals("new cumulative delsI", 1, newCumulativeDelsI - cumulativeDelsI);
@@ -171,7 +171,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
assertU(commit());
// delsI should be reset to 0 after commit
- newDelsI = ((Gauge<Long>) metrics.get(delsIName)).getValue();
+ newDelsI = ((Gauge<Number>) metrics.get(delsIName)).getValue().longValue();
newCumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
assertEquals("new delsI after commit", 0, newDelsI);
assertEquals("new cumulative delsI after commit", 1, newCumulativeDelsI - cumulativeDelsI);
@@ -183,7 +183,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
// now delete all
assertU(delQ("*:*"));
- long newDelsQ = ((Gauge<Long>) metrics.get(delsQName)).getValue();
+ long newDelsQ = ((Gauge<Number>) metrics.get(delsQName)).getValue().longValue();
long newCumulativeDelsQ = ((Meter) metrics.get(cumulativeDelsQName)).getCount();
assertEquals("new delsQ", 1, newDelsQ);
assertEquals("new cumulative delsQ", 1, newCumulativeDelsQ - cumulativeDelsQ);
@@ -193,7 +193,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
assertU(commit());
- newDelsQ = ((Gauge<Long>) metrics.get(delsQName)).getValue();
+ newDelsQ = ((Gauge<Number>) metrics.get(delsQName)).getValue().longValue();
newCumulativeDelsQ = ((Meter) metrics.get(cumulativeDelsQName)).getCount();
assertEquals("new delsQ after commit", 0, newDelsQ);
assertEquals("new cumulative delsQ after commit", 1, newCumulativeDelsQ - cumulativeDelsQ);
@@ -204,11 +204,11 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
// verify final metrics
newCommits = ((Meter) metrics.get(commitsName)).getCount();
assertEquals("new commits", 3, newCommits - commits);
- newAdds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+ newAdds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
assertEquals("new adds", 0, newAdds);
newCumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
assertEquals("new cumulative adds", 2, newCumulativeAdds - cumulativeAdds);
- newDelsI = ((Gauge<Long>) metrics.get(delsIName)).getValue();
+ newDelsI = ((Gauge<Number>) metrics.get(delsIName)).getValue().longValue();
assertEquals("new delsI", 0, newDelsI);
newCumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
assertEquals("new cumulative delsI", 1, newCumulativeDelsI - cumulativeDelsI);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java b/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java
index 2a78d6b..5d98d8b 100644
--- a/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java
+++ b/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java
@@ -16,7 +16,14 @@
*/
package org.apache.solr.update;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import org.apache.lucene.document.Document;
+import org.apache.lucene.index.IndexableField;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrDocument;
@@ -25,6 +32,8 @@ import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
import org.apache.solr.core.SolrCore;
import org.apache.solr.schema.FieldType;
+import org.junit.After;
+import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -33,12 +42,23 @@ import org.junit.Test;
*
*/
public class DocumentBuilderTest extends SolrTestCaseJ4 {
+ static final int save_min_len = DocumentBuilder.MIN_LENGTH_TO_MOVE_LAST;
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig.xml", "schema.xml");
}
+ @AfterClass
+ public static void afterClass() {
+ DocumentBuilder.MIN_LENGTH_TO_MOVE_LAST = save_min_len;
+ }
+
+ @After
+ public void afterTest() {
+ DocumentBuilder.MIN_LENGTH_TO_MOVE_LAST = save_min_len;
+ }
+
@Test
public void testBuildDocument() throws Exception
{
@@ -111,8 +131,8 @@ public class DocumentBuilderTest extends SolrTestCaseJ4 {
doc.addField( "home", "2.2,3.3" );
Document out = DocumentBuilder.toDocument( doc, core.getLatestSchema() );
assertNotNull( out.get( "home" ) );//contains the stored value and term vector, if there is one
- assertNotNull( out.getField( "home_0" + FieldType.POLY_FIELD_SEPARATOR + "double" ) );
- assertNotNull( out.getField( "home_1" + FieldType.POLY_FIELD_SEPARATOR + "double" ) );
+ assertNotNull( out.getField( "home_0" + FieldType.POLY_FIELD_SEPARATOR + System.getProperty("solr.tests.doubleClass", "pdouble") ) );
+ assertNotNull( out.getField( "home_1" + FieldType.POLY_FIELD_SEPARATOR + System.getProperty("solr.tests.doubleClass", "pdouble") ) );
}
/**
@@ -222,7 +242,54 @@ public class DocumentBuilderTest extends SolrTestCaseJ4 {
sif2.setName("foo");
assertFalse(assertSolrInputFieldEquals(sif1, sif2));
+ }
+ public void testMoveLargestLast() {
+ SolrInputDocument inDoc = new SolrInputDocument();
+ String TEXT_FLD = "text"; // not stored. It won't be moved. This value is the longest, however.
+ inDoc.addField(TEXT_FLD,
+ "NOT STORED|" + RandomStrings.randomAsciiOfLength(random(), 4 * DocumentBuilder.MIN_LENGTH_TO_MOVE_LAST));
+
+ String CAT_FLD = "cat"; // stored, multiValued
+ inDoc.addField(CAT_FLD,
+ "STORED V1|");
+ // pretty long value
+ inDoc.addField(CAT_FLD,
+ "STORED V2|" + RandomStrings.randomAsciiOfLength(random(), 2 * DocumentBuilder.MIN_LENGTH_TO_MOVE_LAST));
+ inDoc.addField(CAT_FLD,
+ "STORED V3|" + RandomStrings.randomAsciiOfLength(random(), DocumentBuilder.MIN_LENGTH_TO_MOVE_LAST));
+
+ String SUBJECT_FLD = "subject"; // stored. This value is long, but not long enough.
+ inDoc.addField(SUBJECT_FLD,
+ "2ndplace|" + RandomStrings.randomAsciiOfLength(random(), DocumentBuilder.MIN_LENGTH_TO_MOVE_LAST));
+
+ Document outDoc = DocumentBuilder.toDocument(inDoc, h.getCore().getLatestSchema());
+
+ // filter outDoc by stored fields; convert to list.
+ List<IndexableField> storedFields = StreamSupport.stream(outDoc.spliterator(), false)
+ .filter(f -> f.fieldType().stored()).collect(Collectors.toList());
+ // clip to last 3. We expect these to be for CAT_FLD
+ storedFields = storedFields.subList(storedFields.size() - 3, storedFields.size());
+
+ Iterator<IndexableField> fieldIterator = storedFields.iterator();
+ IndexableField field;
+
+ // Test that we retained the particular value ordering, even though though the 2nd of three was longest
+
+ assertTrue(fieldIterator.hasNext());
+ field = fieldIterator.next();
+ assertEquals(CAT_FLD, field.name());
+ assertTrue(field.stringValue().startsWith("STORED V1|"));
+
+ assertTrue(fieldIterator.hasNext());
+ field = fieldIterator.next();
+ assertEquals(CAT_FLD, field.name());
+ assertTrue(field.stringValue().startsWith("STORED V2|"));
+
+ assertTrue(fieldIterator.hasNext());
+ field = fieldIterator.next();
+ assertEquals(CAT_FLD, field.name());
+ assertTrue(field.stringValue().startsWith("STORED V3|"));
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java b/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
index c9935bb..9985937 100644
--- a/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
+++ b/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
@@ -67,7 +67,7 @@ public class SolrIndexMetricsTest extends SolrTestCaseJ4 {
Map<String, Metric> metrics = registry.getMetrics();
- assertEquals(10, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
+ assertEquals(12, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
// check basic index meters
Timer timer = (Timer)metrics.get("INDEX.merge.minor");
@@ -92,7 +92,8 @@ public class SolrIndexMetricsTest extends SolrTestCaseJ4 {
assertNotNull(registry);
Map<String, Metric> metrics = registry.getMetrics();
- assertEquals(0, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
+ // INDEX.size, INDEX.sizeInBytes
+ assertEquals(2, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
}
@Test
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java b/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
index 4c90bc6..4538e90 100644
--- a/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
+++ b/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesDistrib.java
@@ -71,6 +71,7 @@ import org.slf4j.LoggerFactory;
@Slow
public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private final boolean onlyLeaderIndexes = random().nextBoolean();
@BeforeClass
public static void beforeSuperClass() throws Exception {
@@ -108,7 +109,12 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
iw.decref();
}
}
-
+
+ @Override
+ protected int getRealtimeReplicas() {
+ return onlyLeaderIndexes? 1 : -1;
+ }
+
@After
public void after() {
System.clearProperty("solr.tests.intClassName");
@@ -151,15 +157,18 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
"docValues",Boolean.TRUE));
// Do the tests now:
- reorderedDBQIndividualReplicaTest();
- testDBQUsingUpdatedFieldFromDroppedUpdate();
- outOfOrderDBQsTest();
docValuesUpdateTest();
ensureRtgWorksWithPartialUpdatesTest();
- delayedReorderingFetchesMissingUpdateFromLeaderTest();
outOfOrderUpdatesIndividualReplicaTest();
- outOfOrderDeleteUpdatesIndividualReplicaTest();
- reorderedDBQsWithInPlaceUpdatesShouldNotThrowReplicaInLIRTest();
+ delayedReorderingFetchesMissingUpdateFromLeaderTest();
+ updatingDVsInAVeryOldSegment();
+
+ // TODO Should we combine all/some of these into a single test, so as to cut down on execution time?
+ reorderedDBQIndividualReplicaTest();
+ reorderedDeletesTest();
+ reorderedDBQsSimpleTest();
+ reorderedDBQsResurrectionTest();
+ reorderedDBQsUsingUpdatedValueFromADroppedUpdate();
}
private void mapReplicasToClients() throws KeeperException, InterruptedException {
@@ -195,7 +204,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
final int NUM_RETRIES = 100, WAIT_TIME = 10;
// The following should work: full update to doc 0, in-place update for doc 0, delete doc 0
- private void outOfOrderDBQsTest() throws Exception {
+ private void reorderedDBQsSimpleTest() throws Exception {
clearIndex();
commit();
@@ -243,7 +252,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
threadpool.shutdown();
- assertTrue("Thread pool didn't terminate within 10 secs", threadpool.awaitTermination(10, TimeUnit.SECONDS));
+ assertTrue("Thread pool didn't terminate within 15 secs", threadpool.awaitTermination(15, TimeUnit.SECONDS));
// assert all requests were successful
for (Future<UpdateResponse> resp: updateResponses) {
@@ -256,12 +265,16 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
assertNull("This doc was supposed to have been deleted, but was: " + doc, doc);
}
- log.info("outOfOrderDeleteUpdatesIndividualReplicaTest: This test passed fine...");
+ log.info("reorderedDBQsSimpleTest: This test passed fine...");
clearIndex();
commit();
}
private void reorderedDBQIndividualReplicaTest() throws Exception {
+ if (onlyLeaderIndexes) {
+ log.info("RTG with DBQs are not working in append replicas");
+ return;
+ }
clearIndex();
commit();
@@ -294,7 +307,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
threadpool.shutdown();
- assertTrue("Thread pool didn't terminate within 10 secs", threadpool.awaitTermination(10, TimeUnit.SECONDS));
+ assertTrue("Thread pool didn't terminate within 15 secs", threadpool.awaitTermination(15, TimeUnit.SECONDS));
// assert all requests were successful
for (Future<UpdateResponse> resp: updateResponses) {
@@ -329,7 +342,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
SolrDocumentList results = LEADER.query(params).getResults();
assertEquals(numDocs, results.size());
for (SolrDocument doc : results) {
- luceneDocids.add((int) doc.get("[docid]"));
+ luceneDocids.add((Integer) doc.get("[docid]"));
valuesList.add((Float) doc.get("inplace_updatable_float"));
}
log.info("Initial results: "+results);
@@ -391,6 +404,36 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
/**
+ * Ingest many documents, keep committing. Then update a document from a very old segment.
+ */
+ private void updatingDVsInAVeryOldSegment() throws Exception {
+ clearIndex();
+ commit();
+
+ String id = String.valueOf(Integer.MAX_VALUE);
+ index("id", id, "inplace_updatable_float", "1", "title_s", "newtitle");
+
+ // create 10 more segments
+ for (int i=0; i<10; i++) {
+ buildRandomIndex(101.0F, Collections.emptyList());
+ }
+
+ index("id", id, "inplace_updatable_float", map("inc", "1"));
+
+ for (SolrClient client: new SolrClient[] {LEADER, NONLEADERS.get(0), NONLEADERS.get(1)}) {
+ assertEquals("newtitle", client.getById(id).get("title_s"));
+ assertEquals(2.0f, client.getById(id).get("inplace_updatable_float"));
+ }
+ commit();
+ for (SolrClient client: new SolrClient[] {LEADER, NONLEADERS.get(0), NONLEADERS.get(1)}) {
+ assertEquals("newtitle", client.getById(id).get("title_s"));
+ assertEquals(2.0f, client.getById(id).get("inplace_updatable_float"));
+ }
+
+ log.info("updatingDVsInAVeryOldSegment: This test passed fine...");
+ }
+
+ /**
* Retries the specified 'req' against each SolrClient in "clients" untill the expected number of
* results are returned, at which point the results are verified using assertDocIdsAndValuesInResults
*
@@ -562,7 +605,6 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
private void outOfOrderUpdatesIndividualReplicaTest() throws Exception {
-
clearIndex();
commit();
@@ -610,7 +652,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
threadpool.shutdown();
- assertTrue("Thread pool didn't terminate within 10 secs", threadpool.awaitTermination(10, TimeUnit.SECONDS));
+ assertTrue("Thread pool didn't terminate within 15 secs", threadpool.awaitTermination(15, TimeUnit.SECONDS));
// assert all requests were successful
for (Future<UpdateResponse> resp: updateResponses) {
@@ -633,7 +675,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
// The following should work: full update to doc 0, in-place update for doc 0, delete doc 0
- private void outOfOrderDeleteUpdatesIndividualReplicaTest() throws Exception {
+ private void reorderedDeletesTest() throws Exception {
clearIndex();
commit();
@@ -680,7 +722,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
threadpool.shutdown();
- assertTrue("Thread pool didn't terminate within 10 secs", threadpool.awaitTermination(10, TimeUnit.SECONDS));
+ assertTrue("Thread pool didn't terminate within 15 secs", threadpool.awaitTermination(15, TimeUnit.SECONDS));
// assert all requests were successful
for (Future<UpdateResponse> resp: updateResponses) {
@@ -693,7 +735,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
assertNull("This doc was supposed to have been deleted, but was: " + doc, doc);
}
- log.info("outOfOrderDeleteUpdatesIndividualReplicaTest: This test passed fine...");
+ log.info("reorderedDeletesTest: This test passed fine...");
clearIndex();
commit();
}
@@ -707,7 +749,11 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
DBQ(q=val:10, v=4)
DV(id=x, val=5, ver=3)
*/
- private void reorderedDBQsWithInPlaceUpdatesShouldNotThrowReplicaInLIRTest() throws Exception {
+ private void reorderedDBQsResurrectionTest() throws Exception {
+ if (onlyLeaderIndexes) {
+ log.info("RTG with DBQs are not working in append replicas");
+ return;
+ }
clearIndex();
commit();
@@ -754,7 +800,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
threadpool.shutdown();
- assertTrue("Thread pool didn't terminate within 10 secs", threadpool.awaitTermination(10, TimeUnit.SECONDS));
+ assertTrue("Thread pool didn't terminate within 15 secs", threadpool.awaitTermination(15, TimeUnit.SECONDS));
int successful = 0;
for (Future<UpdateResponse> resp: updateResponses) {
@@ -794,7 +840,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
assertEquals("Client: "+((HttpSolrClient)client).getBaseURL(), 5, doc.getFieldValue(field));
}
- log.info("reorderedDBQsWithInPlaceUpdatesShouldNotThrowReplicaInLIRTest: This test passed fine...");
+ log.info("reorderedDBQsResurrectionTest: This test passed fine...");
clearIndex();
commit();
}
@@ -829,7 +875,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
}
threadpool.shutdown();
- assertTrue("Thread pool didn't terminate within 10 secs", threadpool.awaitTermination(15, TimeUnit.SECONDS));
+ assertTrue("Thread pool didn't terminate within 15 secs", threadpool.awaitTermination(15, TimeUnit.SECONDS));
commit();
@@ -983,7 +1029,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
String baseUrl = getBaseUrl(""+id);
UpdateRequest ur = new UpdateRequest();
- if (random().nextBoolean()) {
+ if (random().nextBoolean() || onlyLeaderIndexes) {
ur.deleteById(""+id);
} else {
ur.deleteByQuery("id:"+id);
@@ -1104,7 +1150,11 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
* inp(id=1,inpfield=14,prevVersion=2,version=3) // will wait till timeout, and then fetch a "not found" from leader
* dbq("inp:14",version=4)
*/
- private void testDBQUsingUpdatedFieldFromDroppedUpdate() throws Exception {
+ private void reorderedDBQsUsingUpdatedValueFromADroppedUpdate() throws Exception {
+ if (onlyLeaderIndexes) {
+ log.info("RTG with DBQs are not working in append replicas");
+ return;
+ }
clearIndex();
commit();
@@ -1161,7 +1211,21 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
assertNull(client.getById("1", params("distrib", "false")));
}
- log.info("testDBQUsingUpdatedFieldFromDroppedUpdate: This test passed fine...");
+ log.info("reorderedDBQsUsingUpdatedValueFromADroppedUpdate: This test passed fine...");
+ }
+
+ @Override
+ public void clearIndex() {
+ super.clearIndex();
+ try {
+ for (SolrClient client: new SolrClient[] {LEADER, NONLEADERS.get(0), NONLEADERS.get(1)}) {
+ if (client != null) {
+ client.request(simulatedDeleteRequest("*:*", -Long.MAX_VALUE));
+ client.commit();
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
-
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesStandalone.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesStandalone.java b/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesStandalone.java
index 9a5031f..877467e 100644
--- a/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesStandalone.java
+++ b/solr/core/src/test/org/apache/solr/update/TestInPlaceUpdatesStandalone.java
@@ -32,6 +32,8 @@ import java.util.Random;
import java.util.Set;
import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.NoMergePolicy;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrClient;
@@ -41,6 +43,7 @@ import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
+import org.apache.solr.index.NoMergePolicyFactory;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.update.processor.DistributedUpdateProcessor;
import org.apache.solr.schema.IndexSchema;
@@ -49,6 +52,7 @@ import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.update.processor.AtomicUpdateDocumentMerger;
import org.apache.solr.util.RefCounted;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -67,6 +71,14 @@ public class TestInPlaceUpdatesStandalone extends SolrTestCaseJ4 {
System.setProperty("solr.tests.floatClassName", random().nextBoolean()? "TrieFloatField": "FloatPointField");
System.setProperty("solr.tests.doubleClassName", random().nextBoolean()? "TrieDoubleField": "DoublePointField");
+ // we need consistent segments that aren't re-ordered on merge because we're
+ // asserting inplace updates happen by checking the internal [docid]
+ systemSetPropertySolrTestsMergePolicyFactory(NoMergePolicyFactory.class.getName());
+
+ // HACK: Don't use a RandomMergePolicy, but only use the mergePolicyFactory that we've just set
+ System.setProperty(SYSTEM_PROPERTY_SOLR_TESTS_USEMERGEPOLICYFACTORY, "true");
+ System.setProperty(SYSTEM_PROPERTY_SOLR_TESTS_USEMERGEPOLICY, "false");
+
initCore("solrconfig-tlog.xml", "schema-inplace-updates.xml");
// sanity check that autocommits are disabled
@@ -75,6 +87,16 @@ public class TestInPlaceUpdatesStandalone extends SolrTestCaseJ4 {
assertEquals(-1, h.getCore().getSolrConfig().getUpdateHandlerInfo().autoCommmitMaxDocs);
assertEquals(-1, h.getCore().getSolrConfig().getUpdateHandlerInfo().autoSoftCommmitMaxDocs);
+ // assert that NoMergePolicy was chosen
+ RefCounted<IndexWriter> iw = h.getCore().getSolrCoreState().getIndexWriter(h.getCore());
+ try {
+ IndexWriter writer = iw.get();
+ assertTrue("Actual merge policy is: " + writer.getConfig().getMergePolicy(),
+ writer.getConfig().getMergePolicy() instanceof NoMergePolicy);
+ } finally {
+ iw.decref();
+ }
+
// validate that the schema was not changed to an unexpected state
IndexSchema schema = h.getCore().getLatestSchema();
for (String fieldName : Arrays.asList("_version_",
@@ -98,6 +120,11 @@ public class TestInPlaceUpdatesStandalone extends SolrTestCaseJ4 {
client = new EmbeddedSolrServer(h.getCoreContainer(), h.coreName);
}
+ @AfterClass
+ public static void afterClass() {
+ client = null;
+ }
+
@After
public void after() {
System.clearProperty("solr.tests.intClassName");
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java b/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java
index 7bae2c9..bfcf015 100644
--- a/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java
+++ b/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java
@@ -1204,7 +1204,6 @@ public class AtomicUpdatesTest extends SolrTestCaseJ4 {
}
- @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-9838")
public void testAtomicUpdateOfFieldsWithDefaultValue() {
// both fields have the same default value (42)
for (String fieldToUpdate : Arrays.asList("intDefault", "intDvoDefault")) {
@@ -1254,7 +1253,7 @@ public class AtomicUpdatesTest extends SolrTestCaseJ4 {
, "count(//doc/*)=6"
);
// do atomic update
- assertU(adoc(sdoc("id", "7", fieldToUpdate, ImmutableMap.of("inc", -555))));
+ assertU(adoc(sdoc("id", "8", fieldToUpdate, ImmutableMap.of("inc", -555))));
assertQ(fieldToUpdate + ": RTG after atomic update"
, req("qt", "/get", "id", "8")
, "count(//doc)=1"
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java b/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
index 8717ad6..35caef8 100644
--- a/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
+++ b/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
@@ -22,6 +22,7 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricFilter;
@@ -44,7 +45,7 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
timer.update(Math.abs(random().nextInt()) + 1, TimeUnit.NANOSECONDS);
}
// obtain timer metrics
- NamedList lst = new NamedList(MetricUtils.timerToMap(timer, false));
+ NamedList lst = new NamedList(MetricUtils.convertTimer(timer, false));
// check that expected metrics were obtained
assertEquals(14, lst.size());
final Snapshot snapshot = timer.getSnapshot();
@@ -78,10 +79,15 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
am.set("foo", 10);
am.set("bar", 1);
am.set("bar", 2);
- MetricUtils.toNamedMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
- false, false, (k, v) -> {
+ Gauge<String> gauge = () -> "foobar";
+ registry.register("gauge", gauge);
+ MetricUtils.toMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
+ false, false, false, (k, o) -> {
+ Map v = (Map)o;
if (k.startsWith("counter")) {
assertEquals(1L, v.get("count"));
+ } else if (k.startsWith("gauge")) {
+ assertEquals("foobar", v.get("value"));
} else if (k.startsWith("timer")) {
assertEquals(1L, v.get("count"));
assertTrue(((Number)v.get("min_ms")).intValue() > 100);
@@ -102,6 +108,47 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
assertEquals(2, update.get("updateCount"));
}
});
+ // test compact format
+ MetricUtils.toMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
+ false, false, true, (k, o) -> {
+ if (k.startsWith("counter")) {
+ assertTrue(o instanceof Long);
+ assertEquals(1L, o);
+ } else if (k.startsWith("gauge")) {
+ assertTrue(o instanceof String);
+ assertEquals("foobar", o);
+ } else if (k.startsWith("timer")) {
+ assertTrue(o instanceof Map);
+ Map v = (Map)o;
+ assertEquals(1L, v.get("count"));
+ assertTrue(((Number)v.get("min_ms")).intValue() > 100);
+ } else if (k.startsWith("meter")) {
+ assertTrue(o instanceof Map);
+ Map v = (Map)o;
+ assertEquals(1L, v.get("count"));
+ } else if (k.startsWith("histogram")) {
+ assertTrue(o instanceof Map);
+ Map v = (Map)o;
+ assertEquals(1L, v.get("count"));
+ } else if (k.startsWith("aggregate")) {
+ assertTrue(o instanceof Map);
+ Map v = (Map)o;
+ assertEquals(2, v.get("count"));
+ Map<String, Object> values = (Map<String, Object>)v.get("values");
+ assertNotNull(values);
+ assertEquals(2, values.size());
+ Map<String, Object> update = (Map<String, Object>)values.get("foo");
+ assertEquals(10, update.get("value"));
+ assertEquals(1, update.get("updateCount"));
+ update = (Map<String, Object>)values.get("bar");
+ assertEquals(2, update.get("value"));
+ assertEquals(2, update.get("updateCount"));
+ } else {
+ Map v = (Map)o;
+ assertEquals(1L, v.get("count"));
+ }
+ });
+
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/server/scripts/cloud-scripts/zkcli.bat
----------------------------------------------------------------------
diff --git a/solr/server/scripts/cloud-scripts/zkcli.bat b/solr/server/scripts/cloud-scripts/zkcli.bat
index c372685..c5d7b72 100644
--- a/solr/server/scripts/cloud-scripts/zkcli.bat
+++ b/solr/server/scripts/cloud-scripts/zkcli.bat
@@ -22,4 +22,4 @@ REM -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD ^
REM -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD
"%JVM%" %SOLR_ZK_CREDS_AND_ACLS% %ZKCLI_JVM_FLAGS% -Dlog4j.configuration="%LOG4J_CONFIG%" ^
--classpath "%SDIR%\..\..\solr-webapp\webapp\WEB-INF\lib\*;%SDIR%\..\..\lib\ext\*" org.apache.solr.cloud.ZkCLI %*
+-classpath "%SDIR%\..\..\solr-webapp\webapp\WEB-INF\lib\*;%SDIR%\..\..\lib\ext\*;%SDIR%\..\..\lib\*" org.apache.solr.cloud.ZkCLI %*
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/887d1b18/solr/server/scripts/cloud-scripts/zkcli.sh
----------------------------------------------------------------------
diff --git a/solr/server/scripts/cloud-scripts/zkcli.sh b/solr/server/scripts/cloud-scripts/zkcli.sh
index df43265..bd971e9 100755
--- a/solr/server/scripts/cloud-scripts/zkcli.sh
+++ b/solr/server/scripts/cloud-scripts/zkcli.sh
@@ -22,5 +22,5 @@ fi
# -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD"
PATH=$JAVA_HOME/bin:$PATH $JVM $SOLR_ZK_CREDS_AND_ACLS $ZKCLI_JVM_FLAGS -Dlog4j.configuration=$log4j_config \
--classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*" org.apache.solr.cloud.ZkCLI ${1+"$@"}
+-classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*:$sdir/../../lib/*" org.apache.solr.cloud.ZkCLI ${1+"$@"}