You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2017/02/26 23:36:51 UTC
[03/72] [abbrv] [partial] lucenenet git commit: Lucene.Net.Tests:
Removed \core directory and put its contents in root directory
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs b/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs
new file mode 100644
index 0000000..5aeaf7c
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs
@@ -0,0 +1,563 @@
+using System;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+ using NUnit.Framework;
+ using AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
+ using DefaultSimilarity = Lucene.Net.Search.Similarities.DefaultSimilarity;
+ using Directory = Lucene.Net.Store.Directory;
+ using Document = Documents.Document;
+ using Field = Field;
+ using FieldType = FieldType;
+ using IndexReader = Lucene.Net.Index.IndexReader;
+
+ /*
+ * 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.
+ */
+
+ using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+ using MockTokenizer = Lucene.Net.Analysis.MockTokenizer;
+ using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+ using Term = Lucene.Net.Index.Term;
+ using TextField = TextField;
+
+ [TestFixture]
+ public class TestMultiTermConstantScore : BaseTestRangeFilter
+ {
+ /// <summary>
+ /// threshold for comparing floats </summary>
+ public const float SCORE_COMP_THRESH = 1e-6f;
+
+ internal static Directory Small;
+ internal static IndexReader Reader;
+
+ public static void AssertEquals(string m, int e, int a)
+ {
+ Assert.AreEqual(e, a, m);
+ }
+
+ /// <summary>
+ /// LUCENENET specific
+ /// Is non-static because NewIndexWriterConfig is no longer static.
+ /// </summary>
+ [OneTimeSetUp]
+ public void BeforeClass()
+ {
+ string[] data = new string[] { "A 1 2 3 4 5 6", "Z 4 5 6", null, "B 2 4 5 6", "Y 3 5 6", null, "C 3 6", "X 4 5 6" };
+
+ Small = NewDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(Random(), Small, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random(), MockTokenizer.WHITESPACE, false)).SetMergePolicy(NewLogMergePolicy()));
+
+ FieldType customType = new FieldType(TextField.TYPE_STORED);
+ customType.IsTokenized = false;
+ for (int i = 0; i < data.Length; i++)
+ {
+ Document doc = new Document();
+ doc.Add(NewField("id", Convert.ToString(i), customType)); // Field.Keyword("id",String.valueOf(i)));
+ doc.Add(NewField("all", "all", customType)); // Field.Keyword("all","all"));
+ if (null != data[i])
+ {
+ doc.Add(NewTextField("data", data[i], Field.Store.YES)); // Field.Text("data",data[i]));
+ }
+ writer.AddDocument(doc);
+ }
+
+ Reader = writer.Reader;
+ writer.Dispose();
+ }
+
+ [OneTimeTearDown]
+ public static void AfterClass()
+ {
+ Reader.Dispose();
+ Small.Dispose();
+ Reader = null;
+ Small = null;
+ }
+
+ /// <summary>
+ /// macro for readability </summary>
+ public static Query Csrq(string f, string l, string h, bool il, bool ih)
+ {
+ TermRangeQuery query = TermRangeQuery.NewStringRange(f, l, h, il, ih);
+ query.MultiTermRewriteMethod = (MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: query=" + query);
+ }
+ return query;
+ }
+
+ public static Query Csrq(string f, string l, string h, bool il, bool ih, MultiTermQuery.RewriteMethod method)
+ {
+ TermRangeQuery query = TermRangeQuery.NewStringRange(f, l, h, il, ih);
+ query.MultiTermRewriteMethod = (method);
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: query=" + query + " method=" + method);
+ }
+ return query;
+ }
+
+ /// <summary>
+ /// macro for readability </summary>
+ public static Query Cspq(Term prefix)
+ {
+ PrefixQuery query = new PrefixQuery(prefix);
+ query.MultiTermRewriteMethod = (MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+ return query;
+ }
+
+ /// <summary>
+ /// macro for readability </summary>
+ public static Query Cswcq(Term wild)
+ {
+ WildcardQuery query = new WildcardQuery(wild);
+ query.MultiTermRewriteMethod = (MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+ return query;
+ }
+
+ [Test]
+ public virtual void TestBasics()
+ {
+ QueryUtils.Check(Csrq("data", "1", "6", T, T));
+ QueryUtils.Check(Csrq("data", "A", "Z", T, T));
+ QueryUtils.CheckUnequal(Csrq("data", "1", "6", T, T), Csrq("data", "A", "Z", T, T));
+
+ QueryUtils.Check(Cspq(new Term("data", "p*u?")));
+ QueryUtils.CheckUnequal(Cspq(new Term("data", "pre*")), Cspq(new Term("data", "pres*")));
+
+ QueryUtils.Check(Cswcq(new Term("data", "p")));
+ QueryUtils.CheckUnequal(Cswcq(new Term("data", "pre*n?t")), Cswcq(new Term("data", "pr*t?j")));
+ }
+
+ [Test]
+ public virtual void TestEqualScores()
+ {
+ // NOTE: uses index build in *this* setUp
+
+ IndexSearcher search = NewSearcher(Reader);
+
+ ScoreDoc[] result;
+
+ // some hits match more terms then others, score should be the same
+
+ result = search.Search(Csrq("data", "1", "6", T, T), null, 1000).ScoreDocs;
+ int numHits = result.Length;
+ AssertEquals("wrong number of results", 6, numHits);
+ float score = result[0].Score;
+ for (int i = 1; i < numHits; i++)
+ {
+ Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+ }
+
+ result = search.Search(Csrq("data", "1", "6", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE), null, 1000).ScoreDocs;
+ numHits = result.Length;
+ AssertEquals("wrong number of results", 6, numHits);
+ for (int i = 0; i < numHits; i++)
+ {
+ Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+ }
+
+ result = search.Search(Csrq("data", "1", "6", T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, 1000).ScoreDocs;
+ numHits = result.Length;
+ AssertEquals("wrong number of results", 6, numHits);
+ for (int i = 0; i < numHits; i++)
+ {
+ Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+ }
+ }
+
+ [Test]
+ public virtual void TestEqualScoresWhenNoHits() // Test for LUCENE-5245: Empty MTQ rewrites should have a consistent norm, so always need to return a CSQ!
+ {
+ // NOTE: uses index build in *this* setUp
+
+ IndexSearcher search = NewSearcher(Reader);
+
+ ScoreDoc[] result;
+
+ TermQuery dummyTerm = new TermQuery(new Term("data", "1"));
+
+ BooleanQuery bq = new BooleanQuery();
+ bq.Add(dummyTerm, Occur.SHOULD); // hits one doc
+ bq.Add(Csrq("data", "#", "#", T, T), Occur.SHOULD); // hits no docs
+ result = search.Search(bq, null, 1000).ScoreDocs;
+ int numHits = result.Length;
+ AssertEquals("wrong number of results", 1, numHits);
+ float score = result[0].Score;
+ for (int i = 1; i < numHits; i++)
+ {
+ Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+ }
+
+ bq = new BooleanQuery();
+ bq.Add(dummyTerm, Occur.SHOULD); // hits one doc
+ bq.Add(Csrq("data", "#", "#", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE), Occur.SHOULD); // hits no docs
+ result = search.Search(bq, null, 1000).ScoreDocs;
+ numHits = result.Length;
+ AssertEquals("wrong number of results", 1, numHits);
+ for (int i = 0; i < numHits; i++)
+ {
+ Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+ }
+
+ bq = new BooleanQuery();
+ bq.Add(dummyTerm, Occur.SHOULD); // hits one doc
+ bq.Add(Csrq("data", "#", "#", T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), Occur.SHOULD); // hits no docs
+ result = search.Search(bq, null, 1000).ScoreDocs;
+ numHits = result.Length;
+ AssertEquals("wrong number of results", 1, numHits);
+ for (int i = 0; i < numHits; i++)
+ {
+ Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+ }
+ }
+
+ [Test]
+ public virtual void TestBoost()
+ {
+ // NOTE: uses index build in *this* setUp
+
+ IndexSearcher search = NewSearcher(Reader);
+
+ // test for correct application of query normalization
+ // must use a non score normalizing method for this.
+
+ search.Similarity = new DefaultSimilarity();
+ Query q = Csrq("data", "1", "6", T, T);
+ q.Boost = 100;
+ search.Search(q, null, new CollectorAnonymousInnerClassHelper(this));
+
+ //
+ // Ensure that boosting works to score one clause of a query higher
+ // than another.
+ //
+ Query q1 = Csrq("data", "A", "A", T, T); // matches document #0
+ q1.Boost = .1f;
+ Query q2 = Csrq("data", "Z", "Z", T, T); // matches document #1
+ BooleanQuery bq = new BooleanQuery(true);
+ bq.Add(q1, Occur.SHOULD);
+ bq.Add(q2, Occur.SHOULD);
+
+ ScoreDoc[] hits = search.Search(bq, null, 1000).ScoreDocs;
+ Assert.AreEqual(1, hits[0].Doc);
+ Assert.AreEqual(0, hits[1].Doc);
+ Assert.IsTrue(hits[0].Score > hits[1].Score);
+
+ q1 = Csrq("data", "A", "A", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE); // matches document #0
+ q1.Boost = .1f;
+ q2 = Csrq("data", "Z", "Z", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE); // matches document #1
+ bq = new BooleanQuery(true);
+ bq.Add(q1, Occur.SHOULD);
+ bq.Add(q2, Occur.SHOULD);
+
+ hits = search.Search(bq, null, 1000).ScoreDocs;
+ Assert.AreEqual(1, hits[0].Doc);
+ Assert.AreEqual(0, hits[1].Doc);
+ Assert.IsTrue(hits[0].Score > hits[1].Score);
+
+ q1 = Csrq("data", "A", "A", T, T); // matches document #0
+ q1.Boost = 10f;
+ q2 = Csrq("data", "Z", "Z", T, T); // matches document #1
+ bq = new BooleanQuery(true);
+ bq.Add(q1, Occur.SHOULD);
+ bq.Add(q2, Occur.SHOULD);
+
+ hits = search.Search(bq, null, 1000).ScoreDocs;
+ Assert.AreEqual(0, hits[0].Doc);
+ Assert.AreEqual(1, hits[1].Doc);
+ Assert.IsTrue(hits[0].Score > hits[1].Score);
+ }
+
+ private class CollectorAnonymousInnerClassHelper : ICollector
+ {
+ private readonly TestMultiTermConstantScore OuterInstance;
+
+ public CollectorAnonymousInnerClassHelper(TestMultiTermConstantScore outerInstance)
+ {
+ this.OuterInstance = outerInstance;
+ @base = 0;
+ }
+
+ private int @base;
+ private Scorer scorer;
+
+ public virtual void SetScorer(Scorer scorer)
+ {
+ this.scorer = scorer;
+ }
+
+ public virtual void Collect(int doc)
+ {
+ Assert.AreEqual(1.0f, scorer.GetScore(), SCORE_COMP_THRESH, "score for doc " + (doc + @base) + " was not correct");
+ }
+
+ public virtual void SetNextReader(AtomicReaderContext context)
+ {
+ @base = context.DocBase;
+ }
+
+ public virtual bool AcceptsDocsOutOfOrder
+ {
+ get { return true; }
+ }
+ }
+
+ [Test]
+ public virtual void TestBooleanOrderUnAffected()
+ {
+ // NOTE: uses index build in *this* setUp
+
+ IndexSearcher search = NewSearcher(Reader);
+
+ // first do a regular TermRangeQuery which uses term expansion so
+ // docs with more terms in range get higher scores
+
+ Query rq = TermRangeQuery.NewStringRange("data", "1", "4", T, T);
+
+ ScoreDoc[] expected = search.Search(rq, null, 1000).ScoreDocs;
+ int numHits = expected.Length;
+
+ // now do a boolean where which also contains a
+ // ConstantScoreRangeQuery and make sure hte order is the same
+
+ BooleanQuery q = new BooleanQuery();
+ q.Add(rq, Occur.MUST); // T, F);
+ q.Add(Csrq("data", "1", "6", T, T), Occur.MUST); // T, F);
+
+ ScoreDoc[] actual = search.Search(q, null, 1000).ScoreDocs;
+
+ AssertEquals("wrong numebr of hits", numHits, actual.Length);
+ for (int i = 0; i < numHits; i++)
+ {
+ AssertEquals("mismatch in docid for hit#" + i, expected[i].Doc, actual[i].Doc);
+ }
+ }
+
+ [Test]
+ public virtual void TestRangeQueryId()
+ {
+ // NOTE: uses index build in *super* setUp
+
+ IndexReader reader = SignedIndexReader;
+ IndexSearcher search = NewSearcher(reader);
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: reader=" + reader);
+ }
+
+ int medId = ((MaxId - MinId) / 2);
+
+ string minIP = Pad(MinId);
+ string maxIP = Pad(MaxId);
+ string medIP = Pad(medId);
+
+ int numDocs = reader.NumDocs;
+
+ AssertEquals("num of docs", numDocs, 1 + MaxId - MinId);
+
+ ScoreDoc[] result;
+
+ // test id, bounded on both ends
+
+ result = search.Search(Csrq("id", minIP, maxIP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("find all", numDocs, result.Length);
+
+ result = search.Search(Csrq("id", minIP, maxIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("find all", numDocs, result.Length);
+
+ result = search.Search(Csrq("id", minIP, maxIP, T, F), null, numDocs).ScoreDocs;
+ AssertEquals("all but last", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("id", minIP, maxIP, T, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("all but last", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("id", minIP, maxIP, F, T), null, numDocs).ScoreDocs;
+ AssertEquals("all but first", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("id", minIP, maxIP, F, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("all but first", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("id", minIP, maxIP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("all but ends", numDocs - 2, result.Length);
+
+ result = search.Search(Csrq("id", minIP, maxIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("all but ends", numDocs - 2, result.Length);
+
+ result = search.Search(Csrq("id", medIP, maxIP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("med and up", 1 + MaxId - medId, result.Length);
+
+ result = search.Search(Csrq("id", medIP, maxIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("med and up", 1 + MaxId - medId, result.Length);
+
+ result = search.Search(Csrq("id", minIP, medIP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("up to med", 1 + medId - MinId, result.Length);
+
+ result = search.Search(Csrq("id", minIP, medIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("up to med", 1 + medId - MinId, result.Length);
+
+ // unbounded id
+
+ result = search.Search(Csrq("id", minIP, null, T, F), null, numDocs).ScoreDocs;
+ AssertEquals("min and up", numDocs, result.Length);
+
+ result = search.Search(Csrq("id", null, maxIP, F, T), null, numDocs).ScoreDocs;
+ AssertEquals("max and down", numDocs, result.Length);
+
+ result = search.Search(Csrq("id", minIP, null, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("not min, but up", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("id", null, maxIP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("not max, but down", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("id", medIP, maxIP, T, F), null, numDocs).ScoreDocs;
+ AssertEquals("med and up, not max", MaxId - medId, result.Length);
+
+ result = search.Search(Csrq("id", minIP, medIP, F, T), null, numDocs).ScoreDocs;
+ AssertEquals("not min, up to med", medId - MinId, result.Length);
+
+ // very small sets
+
+ result = search.Search(Csrq("id", minIP, minIP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("min,min,F,F", 0, result.Length);
+
+ result = search.Search(Csrq("id", minIP, minIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("min,min,F,F", 0, result.Length);
+
+ result = search.Search(Csrq("id", medIP, medIP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("med,med,F,F", 0, result.Length);
+
+ result = search.Search(Csrq("id", medIP, medIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("med,med,F,F", 0, result.Length);
+
+ result = search.Search(Csrq("id", maxIP, maxIP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("max,max,F,F", 0, result.Length);
+
+ result = search.Search(Csrq("id", maxIP, maxIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("max,max,F,F", 0, result.Length);
+
+ result = search.Search(Csrq("id", minIP, minIP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("min,min,T,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", minIP, minIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("min,min,T,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", null, minIP, F, T), null, numDocs).ScoreDocs;
+ AssertEquals("nul,min,F,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", null, minIP, F, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("nul,min,F,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", maxIP, maxIP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("max,max,T,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", maxIP, maxIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("max,max,T,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", maxIP, null, T, F), null, numDocs).ScoreDocs;
+ AssertEquals("max,nul,T,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", maxIP, null, T, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("max,nul,T,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", medIP, medIP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("med,med,T,T", 1, result.Length);
+
+ result = search.Search(Csrq("id", medIP, medIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+ AssertEquals("med,med,T,T", 1, result.Length);
+ }
+
+ [Test]
+ public virtual void TestRangeQueryRand()
+ {
+ // NOTE: uses index build in *super* setUp
+
+ IndexReader reader = SignedIndexReader;
+ IndexSearcher search = NewSearcher(reader);
+
+ string minRP = Pad(SignedIndexDir.MinR);
+ string maxRP = Pad(SignedIndexDir.MaxR);
+
+ int numDocs = reader.NumDocs;
+
+ AssertEquals("num of docs", numDocs, 1 + MaxId - MinId);
+
+ ScoreDoc[] result;
+
+ // test extremes, bounded on both ends
+
+ result = search.Search(Csrq("rand", minRP, maxRP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("find all", numDocs, result.Length);
+
+ result = search.Search(Csrq("rand", minRP, maxRP, T, F), null, numDocs).ScoreDocs;
+ AssertEquals("all but biggest", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("rand", minRP, maxRP, F, T), null, numDocs).ScoreDocs;
+ AssertEquals("all but smallest", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("rand", minRP, maxRP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("all but extremes", numDocs - 2, result.Length);
+
+ // unbounded
+
+ result = search.Search(Csrq("rand", minRP, null, T, F), null, numDocs).ScoreDocs;
+ AssertEquals("smallest and up", numDocs, result.Length);
+
+ result = search.Search(Csrq("rand", null, maxRP, F, T), null, numDocs).ScoreDocs;
+ AssertEquals("biggest and down", numDocs, result.Length);
+
+ result = search.Search(Csrq("rand", minRP, null, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("not smallest, but up", numDocs - 1, result.Length);
+
+ result = search.Search(Csrq("rand", null, maxRP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("not biggest, but down", numDocs - 1, result.Length);
+
+ // very small sets
+
+ result = search.Search(Csrq("rand", minRP, minRP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("min,min,F,F", 0, result.Length);
+ result = search.Search(Csrq("rand", maxRP, maxRP, F, F), null, numDocs).ScoreDocs;
+ AssertEquals("max,max,F,F", 0, result.Length);
+
+ result = search.Search(Csrq("rand", minRP, minRP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("min,min,T,T", 1, result.Length);
+ result = search.Search(Csrq("rand", null, minRP, F, T), null, numDocs).ScoreDocs;
+ AssertEquals("nul,min,F,T", 1, result.Length);
+
+ result = search.Search(Csrq("rand", maxRP, maxRP, T, T), null, numDocs).ScoreDocs;
+ AssertEquals("max,max,T,T", 1, result.Length);
+ result = search.Search(Csrq("rand", maxRP, null, T, F), null, numDocs).ScoreDocs;
+ AssertEquals("max,nul,T,T", 1, result.Length);
+ }
+
+
+ #region SorterTestBase
+ // LUCENENET NOTE: Tests in a base class are not pulled into the correct
+ // context in Visual Studio. This fixes that with the minimum amount of code necessary
+ // to run them in the correct context without duplicating all of the tests.
+
+ [Test]
+ public override void TestPad()
+ {
+ base.TestPad();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs b/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs
new file mode 100644
index 0000000..0d7afc5
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Diagnostics;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+ using NUnit.Framework;
+ using System.Runtime.CompilerServices;
+ using Util;
+ using AttributeSource = Lucene.Net.Util.AttributeSource;
+ using BytesRef = Lucene.Net.Util.BytesRef;
+ using Directory = Lucene.Net.Store.Directory;
+ using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+ using Document = Documents.Document;
+ using Field = Field;
+ using IndexReader = Lucene.Net.Index.IndexReader;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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.
+ */
+
+ using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+ using MultiReader = Lucene.Net.Index.MultiReader;
+ using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+ using Term = Lucene.Net.Index.Term;
+ using Terms = Lucene.Net.Index.Terms;
+ using TermsEnum = Lucene.Net.Index.TermsEnum;
+
+ [TestFixture]
+ public class TestMultiTermQueryRewrites : LuceneTestCase
+ {
+ internal static Directory Dir, Sdir1, Sdir2;
+ internal static IndexReader Reader, MultiReader, MultiReaderDupls;
+ internal static IndexSearcher Searcher, MultiSearcher, MultiSearcherDupls;
+
+ /// <summary>
+ /// LUCENENET specific
+ /// Is non-static because Similarity and TimeZone are not static.
+ /// </summary>
+ [OneTimeSetUp]
+ public void BeforeClass()
+ {
+ Dir = NewDirectory();
+ Sdir1 = NewDirectory();
+ Sdir2 = NewDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(Random(), Dir, new MockAnalyzer(Random()), Similarity, TimeZone);
+ RandomIndexWriter swriter1 = new RandomIndexWriter(Random(), Sdir1, new MockAnalyzer(Random()), Similarity, TimeZone);
+ RandomIndexWriter swriter2 = new RandomIndexWriter(Random(), Sdir2, new MockAnalyzer(Random()), Similarity, TimeZone);
+
+ for (int i = 0; i < 10; i++)
+ {
+ Document doc = new Document();
+ doc.Add(NewStringField("data", Convert.ToString(i), Field.Store.NO));
+ writer.AddDocument(doc);
+ ((i % 2 == 0) ? swriter1 : swriter2).AddDocument(doc);
+ }
+ writer.ForceMerge(1);
+ swriter1.ForceMerge(1);
+ swriter2.ForceMerge(1);
+ writer.Dispose();
+ swriter1.Dispose();
+ swriter2.Dispose();
+
+ Reader = DirectoryReader.Open(Dir);
+ Searcher = NewSearcher(Reader);
+
+ MultiReader = new MultiReader(new IndexReader[] { DirectoryReader.Open(Sdir1), DirectoryReader.Open(Sdir2) }, true);
+ MultiSearcher = NewSearcher(MultiReader);
+
+ MultiReaderDupls = new MultiReader(new IndexReader[] { DirectoryReader.Open(Sdir1), DirectoryReader.Open(Dir) }, true);
+ MultiSearcherDupls = NewSearcher(MultiReaderDupls);
+ }
+
+ [OneTimeTearDown]
+ public static void AfterClass()
+ {
+ Reader.Dispose();
+ MultiReader.Dispose();
+ MultiReaderDupls.Dispose();
+ Dir.Dispose();
+ Sdir1.Dispose();
+ Sdir2.Dispose();
+ Reader = MultiReader = MultiReaderDupls = null;
+ Searcher = MultiSearcher = MultiSearcherDupls = null;
+ Dir = Sdir1 = Sdir2 = null;
+ }
+
+ private Query ExtractInnerQuery(Query q)
+ {
+ if (q is ConstantScoreQuery)
+ {
+ // wrapped as ConstantScoreQuery
+ q = ((ConstantScoreQuery)q).Query;
+ }
+ return q;
+ }
+
+ private Term ExtractTerm(Query q)
+ {
+ q = ExtractInnerQuery(q);
+ return ((TermQuery)q).Term;
+ }
+
+ private void CheckBooleanQueryOrder(Query q)
+ {
+ q = ExtractInnerQuery(q);
+ BooleanQuery bq = (BooleanQuery)q;
+ Term last = null, act;
+ foreach (BooleanClause clause in bq.Clauses)
+ {
+ act = ExtractTerm(clause.Query);
+ if (last != null)
+ {
+ Assert.IsTrue(last.CompareTo(act) < 0, "sort order of terms in BQ violated");
+ }
+ last = act;
+ }
+ }
+
+ private void CheckDuplicateTerms(MultiTermQuery.RewriteMethod method)
+ {
+ MultiTermQuery mtq = TermRangeQuery.NewStringRange("data", "2", "7", true, true);
+ mtq.MultiTermRewriteMethod = (method);
+ Query q1 = Searcher.Rewrite(mtq);
+ Query q2 = MultiSearcher.Rewrite(mtq);
+ Query q3 = MultiSearcherDupls.Rewrite(mtq);
+ if (VERBOSE)
+ {
+ Console.WriteLine();
+ Console.WriteLine("single segment: " + q1);
+ Console.WriteLine("multi segment: " + q2);
+ Console.WriteLine("multi segment with duplicates: " + q3);
+ }
+ Assert.IsTrue(q1.Equals(q2), "The multi-segment case must produce same rewritten query");
+ Assert.IsTrue(q1.Equals(q3), "The multi-segment case with duplicates must produce same rewritten query");
+ CheckBooleanQueryOrder(q1);
+ CheckBooleanQueryOrder(q2);
+ CheckBooleanQueryOrder(q3);
+ }
+
+ [Test]
+ public virtual void TestRewritesWithDuplicateTerms()
+ {
+ CheckDuplicateTerms(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
+
+ CheckDuplicateTerms(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE);
+
+ // use a large PQ here to only test duplicate terms and dont mix up when all scores are equal
+ CheckDuplicateTerms(new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(1024));
+ CheckDuplicateTerms(new MultiTermQuery.TopTermsBoostOnlyBooleanQueryRewrite(1024));
+
+ // Test auto rewrite (but only boolean mode), so we set the limits to large values to always get a BQ
+ MultiTermQuery.ConstantScoreAutoRewrite rewrite = new MultiTermQuery.ConstantScoreAutoRewrite();
+ rewrite.TermCountCutoff = int.MaxValue;
+ rewrite.DocCountPercent = 100.0;
+ CheckDuplicateTerms(rewrite);
+ }
+
+ private void CheckBooleanQueryBoosts(BooleanQuery bq)
+ {
+ foreach (BooleanClause clause in bq.Clauses)
+ {
+ TermQuery mtq = (TermQuery)clause.Query;
+ Assert.AreEqual(Convert.ToSingle(mtq.Term.Text()), mtq.Boost, 0, "Parallel sorting of boosts in rewrite mode broken");
+ }
+ }
+
+ private void CheckBoosts(MultiTermQuery.RewriteMethod method)
+ {
+ MultiTermQuery mtq = new MultiTermQueryAnonymousInnerClassHelper(this);
+ mtq.MultiTermRewriteMethod = (method);
+ Query q1 = Searcher.Rewrite(mtq);
+ Query q2 = MultiSearcher.Rewrite(mtq);
+ Query q3 = MultiSearcherDupls.Rewrite(mtq);
+ if (VERBOSE)
+ {
+ Console.WriteLine();
+ Console.WriteLine("single segment: " + q1);
+ Console.WriteLine("multi segment: " + q2);
+ Console.WriteLine("multi segment with duplicates: " + q3);
+ }
+ Assert.IsTrue(q1.Equals(q2), "The multi-segment case must produce same rewritten query");
+ Assert.IsTrue(q1.Equals(q3), "The multi-segment case with duplicates must produce same rewritten query");
+ CheckBooleanQueryBoosts((BooleanQuery)q1);
+ CheckBooleanQueryBoosts((BooleanQuery)q2);
+ CheckBooleanQueryBoosts((BooleanQuery)q3);
+ }
+
+ private class MultiTermQueryAnonymousInnerClassHelper : MultiTermQuery
+ {
+ private readonly TestMultiTermQueryRewrites OuterInstance;
+
+ public MultiTermQueryAnonymousInnerClassHelper(TestMultiTermQueryRewrites outerInstance)
+ : base("data")
+ {
+ this.OuterInstance = outerInstance;
+ }
+
+ protected override TermsEnum GetTermsEnum(Terms terms, AttributeSource atts)
+ {
+ return new TermRangeTermsEnumAnonymousInnerClassHelper(this, terms.GetIterator(null), new BytesRef("2"), new BytesRef("7"));
+ }
+
+ private class TermRangeTermsEnumAnonymousInnerClassHelper : TermRangeTermsEnum
+ {
+ private readonly MultiTermQueryAnonymousInnerClassHelper OuterInstance;
+
+ public TermRangeTermsEnumAnonymousInnerClassHelper(MultiTermQueryAnonymousInnerClassHelper outerInstance, TermsEnum iterator, BytesRef bref1, BytesRef bref2)
+ : base(iterator, bref1, bref2, true, true)
+ {
+ this.OuterInstance = outerInstance;
+ boostAtt = Attributes.AddAttribute<IBoostAttribute>();
+ }
+
+ internal readonly IBoostAttribute boostAtt;
+
+ protected override AcceptStatus Accept(BytesRef term)
+ {
+ boostAtt.Boost = Convert.ToSingle(term.Utf8ToString());
+ return base.Accept(term);
+ }
+ }
+
+ public override string ToString(string field)
+ {
+ return "dummy";
+ }
+ }
+
+ [Test]
+ public virtual void TestBoosts()
+ {
+ CheckBoosts(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
+
+ // use a large PQ here to only test boosts and dont mix up when all scores are equal
+ CheckBoosts(new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(1024));
+ }
+
+ private void CheckMaxClauseLimitation(MultiTermQuery.RewriteMethod method, [CallerMemberName] string memberName = "")
+ {
+ int savedMaxClauseCount = BooleanQuery.MaxClauseCount;
+ BooleanQuery.MaxClauseCount = 3;
+
+ MultiTermQuery mtq = TermRangeQuery.NewStringRange("data", "2", "7", true, true);
+ mtq.MultiTermRewriteMethod = (method);
+ try
+ {
+ MultiSearcherDupls.Rewrite(mtq);
+ Assert.Fail("Should throw BooleanQuery.TooManyClauses");
+ }
+ catch (BooleanQuery.TooManyClauses e)
+ {
+ // Maybe remove this assert in later versions, when internal API changes:
+ Assert.AreEqual("CheckMaxClauseCount", new StackTrace(e, false).GetFrames()[0].GetMethod().Name); //, "Should throw BooleanQuery.TooManyClauses with a stacktrace containing checkMaxClauseCount()");
+ }
+ finally
+ {
+ BooleanQuery.MaxClauseCount = savedMaxClauseCount;
+ }
+ }
+
+ private void CheckNoMaxClauseLimitation(MultiTermQuery.RewriteMethod method)
+ {
+ int savedMaxClauseCount = BooleanQuery.MaxClauseCount;
+ BooleanQuery.MaxClauseCount = 3;
+
+ MultiTermQuery mtq = TermRangeQuery.NewStringRange("data", "2", "7", true, true);
+ mtq.MultiTermRewriteMethod = (method);
+ try
+ {
+ MultiSearcherDupls.Rewrite(mtq);
+ }
+ finally
+ {
+ BooleanQuery.MaxClauseCount = savedMaxClauseCount;
+ }
+ }
+
+ [Test]
+ public virtual void TestMaxClauseLimitations()
+ {
+ CheckMaxClauseLimitation(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
+ CheckMaxClauseLimitation(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE);
+
+ CheckNoMaxClauseLimitation(MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+ CheckNoMaxClauseLimitation(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
+ CheckNoMaxClauseLimitation(new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(1024));
+ CheckNoMaxClauseLimitation(new MultiTermQuery.TopTermsBoostOnlyBooleanQueryRewrite(1024));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
new file mode 100644
index 0000000..89607cf
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
@@ -0,0 +1,244 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Support;
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+
+namespace Lucene.Net.Search
+{
+
+ using NUnit.Framework;
+ using System.IO;
+ using Directory = Lucene.Net.Store.Directory;
+ using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+ using English = Lucene.Net.Util.English;
+ using Fields = Lucene.Net.Index.Fields;
+ using IndexReader = Lucene.Net.Index.IndexReader;
+ using IndexWriter = Lucene.Net.Index.IndexWriter;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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.
+ */
+
+ using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+ using Terms = Lucene.Net.Index.Terms;
+ using TermsEnum = Lucene.Net.Index.TermsEnum;
+
+ [TestFixture]
+ public class TestMultiThreadTermVectors : LuceneTestCase
+ {
+ private Directory Directory;
+ public int NumDocs = 100;
+ public int NumThreads = 3;
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ Directory = NewDirectory();
+ IndexWriter writer = new IndexWriter(Directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetMergePolicy(NewLogMergePolicy()));
+ //writer.setNoCFSRatio(0.0);
+ //writer.infoStream = System.out;
+ FieldType customType = new FieldType(TextField.TYPE_STORED);
+ customType.IsTokenized = false;
+ customType.StoreTermVectors = true;
+ for (int i = 0; i < NumDocs; i++)
+ {
+ Documents.Document doc = new Documents.Document();
+ Field fld = NewField("field", English.IntToEnglish(i), customType);
+ doc.Add(fld);
+ writer.AddDocument(doc);
+ }
+ writer.Dispose();
+ }
+
+ [TearDown]
+ public override void TearDown()
+ {
+ Directory.Dispose();
+ base.TearDown();
+ }
+
+ [Test]
+ public virtual void Test()
+ {
+ IndexReader reader = null;
+
+ try
+ {
+ reader = DirectoryReader.Open(Directory);
+ for (int i = 1; i <= NumThreads; i++)
+ {
+ TestTermPositionVectors(reader, i);
+ }
+ }
+ catch (IOException ioe)
+ {
+ Assert.Fail(ioe.Message);
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ try
+ {
+ /// <summary>
+ /// close the opened reader </summary>
+ reader.Dispose();
+ }
+ catch (IOException ioe)
+ {
+ Console.WriteLine(ioe.ToString());
+ Console.Write(ioe.StackTrace);
+ }
+ }
+ }
+ }
+
+ public virtual void TestTermPositionVectors(IndexReader reader, int threadCount)
+ {
+ MultiThreadTermVectorsReader[] mtr = new MultiThreadTermVectorsReader[threadCount];
+ for (int i = 0; i < threadCount; i++)
+ {
+ mtr[i] = new MultiThreadTermVectorsReader();
+ mtr[i].Init(reader);
+ }
+
+ // run until all threads finished
+ int threadsAlive = mtr.Length;
+ while (threadsAlive > 0)
+ {
+ //System.out.println("Threads alive");
+ Thread.Sleep(10);
+ threadsAlive = mtr.Length;
+ for (int i = 0; i < mtr.Length; i++)
+ {
+ if (mtr[i].Alive == true)
+ {
+ break;
+ }
+
+ threadsAlive--;
+ }
+ }
+
+ long totalTime = 0L;
+ for (int i = 0; i < mtr.Length; i++)
+ {
+ totalTime += mtr[i].TimeElapsed;
+ mtr[i] = null;
+ }
+
+ //System.out.println("threadcount: " + mtr.Length + " average term vector time: " + totalTime/mtr.Length);
+ }
+ }
+
+ internal class MultiThreadTermVectorsReader : IThreadRunnable
+ {
+ private IndexReader Reader = null;
+ private ThreadClass t = null;
+
+ private readonly int RunsToDo = 100;
+ internal long TimeElapsed = 0;
+
+ public virtual void Init(IndexReader reader)
+ {
+ this.Reader = reader;
+ TimeElapsed = 0;
+ t = new ThreadClass(new System.Threading.ThreadStart(this.Run));
+ t.Start();
+ }
+
+ public virtual bool Alive
+ {
+ get
+ {
+ if (t == null)
+ {
+ return false;
+ }
+
+ return t.IsAlive;
+ }
+ }
+
+ [Test]
+ public void Run()
+ {
+ try
+ {
+ // run the test 100 times
+ for (int i = 0; i < RunsToDo; i++)
+ {
+ TestTermVectors();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ Console.Write(e.StackTrace);
+ }
+ return;
+ }
+
+ private void TestTermVectors()
+ {
+ // check:
+ int numDocs = Reader.NumDocs;
+ long start = 0L;
+ for (int docId = 0; docId < numDocs; docId++)
+ {
+ start = Environment.TickCount;
+ Fields vectors = Reader.GetTermVectors(docId);
+ TimeElapsed += Environment.TickCount - start;
+
+ // verify vectors result
+ VerifyVectors(vectors, docId);
+
+ start = Environment.TickCount;
+ Terms vector = Reader.GetTermVectors(docId).GetTerms("field");
+ TimeElapsed += Environment.TickCount - start;
+
+ VerifyVector(vector.GetIterator(null), docId);
+ }
+ }
+
+ private void VerifyVectors(Fields vectors, int num)
+ {
+ foreach (string field in vectors)
+ {
+ Terms terms = vectors.GetTerms(field);
+ Debug.Assert(terms != null);
+ VerifyVector(terms.GetIterator(null), num);
+ }
+ }
+
+ private void VerifyVector(TermsEnum vector, int num)
+ {
+ StringBuilder temp = new StringBuilder();
+ while (vector.Next() != null)
+ {
+ temp.Append(vector.Term.Utf8ToString());
+ }
+ if (!English.IntToEnglish(num).Trim().Equals(temp.ToString().Trim()))
+ {
+ Console.WriteLine("wrong term result");
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs b/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs
new file mode 100644
index 0000000..5c66182
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs
@@ -0,0 +1,88 @@
+using System.Globalization;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+ using NUnit.Framework;
+ using Directory = Lucene.Net.Store.Directory;
+ using Document = Documents.Document;
+ using Field = Field;
+ using IndexReader = Lucene.Net.Index.IndexReader;
+ using Int32Field = Int32Field;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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.
+ */
+
+ using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+ using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+ using TestUtil = Lucene.Net.Util.TestUtil;
+
+ [TestFixture]
+ public class TestMultiValuedNumericRangeQuery : LuceneTestCase
+ {
+ /// <summary>
+ /// Tests NumericRangeQuery on a multi-valued field (multiple numeric values per document).
+ /// this test ensures, that a classical TermRangeQuery returns exactly the same document numbers as
+ /// NumericRangeQuery (see SOLR-1322 for discussion) and the multiple precision terms per numeric value
+ /// do not interfere with multiple numeric values.
+ /// </summary>
+ [Test]
+ public virtual void TestMultiValuedNRQ()
+ {
+ Directory directory = NewDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(Random(), directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetMaxBufferedDocs(TestUtil.NextInt(Random(), 50, 1000)));
+ const string format = "D11";
+
+ int num = AtLeast(500);
+ for (int l = 0; l < num; l++)
+ {
+ Document doc = new Document();
+ for (int m = 0, c = Random().Next(10); m <= c; m++)
+ {
+ int value = Random().Next(int.MaxValue);
+ doc.Add(NewStringField("asc", value.ToString(format), Field.Store.NO));
+ doc.Add(new Int32Field("trie", value, Field.Store.NO));
+ }
+ writer.AddDocument(doc);
+ }
+ IndexReader reader = writer.Reader;
+ writer.Dispose();
+
+ IndexSearcher searcher = NewSearcher(reader);
+ num = AtLeast(50);
+ for (int i = 0; i < num; i++)
+ {
+ int lower = Random().Next(int.MaxValue);
+ int upper = Random().Next(int.MaxValue);
+ if (lower > upper)
+ {
+ int a = lower;
+ lower = upper;
+ upper = a;
+ }
+ TermRangeQuery cq = TermRangeQuery.NewStringRange("asc", lower.ToString(format), upper.ToString(format), true, true);
+ NumericRangeQuery<int> tq = NumericRangeQuery.NewInt32Range("trie", lower, upper, true, true);
+ TopDocs trTopDocs = searcher.Search(cq, 1);
+ TopDocs nrTopDocs = searcher.Search(tq, 1);
+ Assert.AreEqual(trTopDocs.TotalHits, nrTopDocs.TotalHits, "Returned count for NumericRangeQuery and TermRangeQuery must be equal");
+ }
+ reader.Dispose();
+ directory.Dispose();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs b/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs
new file mode 100644
index 0000000..c445929
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs
@@ -0,0 +1,113 @@
+namespace Lucene.Net.Search
+{
+ using NUnit.Framework;
+ using Directory = Lucene.Net.Store.Directory;
+
+ /*
+ * 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.
+ */
+
+ using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+ using IndexReader = Lucene.Net.Index.IndexReader;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+ using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+ using Term = Lucene.Net.Index.Term;
+
+ [TestFixture]
+ public class TestNGramPhraseQuery : LuceneTestCase
+ {
+ private static IndexReader Reader;
+ private static Directory Directory;
+
+ /// <summary>
+ /// LUCENENET specific
+ /// Is non-static because Similarity and TimeZone are not static.
+ /// </summary>
+ [OneTimeSetUp]
+ public void BeforeClass()
+ {
+ Directory = NewDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(Random(), Directory, Similarity, TimeZone);
+ writer.Dispose();
+ Reader = DirectoryReader.Open(Directory);
+ }
+
+ [OneTimeTearDown]
+ public static void AfterClass()
+ {
+ Reader.Dispose();
+ Reader = null;
+ Directory.Dispose();
+ Directory = null;
+ }
+
+ [Test]
+ public virtual void TestRewrite()
+ {
+ // bi-gram test ABC => AB/BC => AB/BC
+ PhraseQuery pq1 = new NGramPhraseQuery(2);
+ pq1.Add(new Term("f", "AB"));
+ pq1.Add(new Term("f", "BC"));
+
+ Query q = pq1.Rewrite(Reader);
+ Assert.IsTrue(q is NGramPhraseQuery);
+ Assert.AreSame(pq1, q);
+ pq1 = (NGramPhraseQuery)q;
+ Assert.AreEqual(new Term[] { new Term("f", "AB"), new Term("f", "BC") }, pq1.GetTerms());
+ Assert.AreEqual(new int[] { 0, 1 }, pq1.GetPositions());
+
+ // bi-gram test ABCD => AB/BC/CD => AB//CD
+ PhraseQuery pq2 = new NGramPhraseQuery(2);
+ pq2.Add(new Term("f", "AB"));
+ pq2.Add(new Term("f", "BC"));
+ pq2.Add(new Term("f", "CD"));
+
+ q = pq2.Rewrite(Reader);
+ Assert.IsTrue(q is PhraseQuery);
+ Assert.AreNotSame(pq2, q);
+ pq2 = (PhraseQuery)q;
+ Assert.AreEqual(new Term[] { new Term("f", "AB"), new Term("f", "CD") }, pq2.GetTerms());
+ Assert.AreEqual(new int[] { 0, 2 }, pq2.GetPositions());
+
+ // tri-gram test ABCDEFGH => ABC/BCD/CDE/DEF/EFG/FGH => ABC///DEF//FGH
+ PhraseQuery pq3 = new NGramPhraseQuery(3);
+ pq3.Add(new Term("f", "ABC"));
+ pq3.Add(new Term("f", "BCD"));
+ pq3.Add(new Term("f", "CDE"));
+ pq3.Add(new Term("f", "DEF"));
+ pq3.Add(new Term("f", "EFG"));
+ pq3.Add(new Term("f", "FGH"));
+
+ q = pq3.Rewrite(Reader);
+ Assert.IsTrue(q is PhraseQuery);
+ Assert.AreNotSame(pq3, q);
+ pq3 = (PhraseQuery)q;
+ Assert.AreEqual(new Term[] { new Term("f", "ABC"), new Term("f", "DEF"), new Term("f", "FGH") }, pq3.GetTerms());
+ Assert.AreEqual(new int[] { 0, 3, 5 }, pq3.GetPositions());
+
+ // LUCENE-4970: boosting test
+ PhraseQuery pq4 = new NGramPhraseQuery(2);
+ pq4.Add(new Term("f", "AB"));
+ pq4.Add(new Term("f", "BC"));
+ pq4.Add(new Term("f", "CD"));
+ pq4.Boost = 100.0F;
+
+ q = pq4.Rewrite(Reader);
+ Assert.AreNotSame(pq4, q);
+ Assert.AreEqual(pq4.Boost, q.Boost, 0.1f);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestNot.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestNot.cs b/src/Lucene.Net.Tests/Search/TestNot.cs
new file mode 100644
index 0000000..99611aa
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestNot.cs
@@ -0,0 +1,65 @@
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+ using NUnit.Framework;
+ using Directory = Lucene.Net.Store.Directory;
+ using Document = Documents.Document;
+
+ /*
+ * 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.
+ */
+
+ using Field = Field;
+ using IndexReader = Lucene.Net.Index.IndexReader;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+ using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+ using Term = Lucene.Net.Index.Term;
+
+ /// <summary>
+ /// Similarity unit test.
+ ///
+ ///
+ /// </summary>
+ [TestFixture]
+ public class TestNot : LuceneTestCase
+ {
+ [Test]
+ public virtual void TestNot_Mem()
+ {
+ Directory store = NewDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(Random(), store, Similarity, TimeZone);
+
+ Document d1 = new Document();
+ d1.Add(NewTextField("field", "a b", Field.Store.YES));
+
+ writer.AddDocument(d1);
+ IndexReader reader = writer.Reader;
+
+ IndexSearcher searcher = NewSearcher(reader);
+
+ BooleanQuery query = new BooleanQuery();
+ query.Add(new TermQuery(new Term("field", "a")), Occur.SHOULD);
+ query.Add(new TermQuery(new Term("field", "b")), Occur.MUST_NOT);
+
+ ScoreDoc[] hits = searcher.Search(query, null, 1000).ScoreDocs;
+ Assert.AreEqual(0, hits.Length);
+ writer.Dispose();
+ reader.Dispose();
+ store.Dispose();
+ }
+ }
+}
\ No newline at end of file