| using Lucene.Net.Analysis; |
| using Lucene.Net.Documents; |
| using Lucene.Net.Index; |
| using Lucene.Net.Search; |
| using Lucene.Net.Util; |
| using NUnit.Framework; |
| using System; |
| using System.Collections.Generic; |
| using System.IO; |
| using Assert = Lucene.Net.TestFramework.Assert; |
| using Console = Lucene.Net.Util.SystemConsole; |
| using Occur = Lucene.Net.Search.Occur; |
| |
| namespace Lucene.Net |
| { |
| /* |
| * 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. |
| */ |
| |
| /// <summary> |
| /// JUnit adaptation of an older test case SearchTest. </summary> |
| public class TestSearch_ : LuceneTestCase |
| { |
| [Test] |
| public virtual void TestNegativeQueryBoost() |
| { |
| Query q = new TermQuery(new Term("foo", "bar")); |
| q.Boost = -42f; |
| Assert.AreEqual(-42f, q.Boost, 0.0f); |
| |
| Store.Directory directory = NewDirectory(); |
| try |
| { |
| Analyzer analyzer = new MockAnalyzer(Random); |
| IndexWriterConfig conf = NewIndexWriterConfig(TEST_VERSION_CURRENT, analyzer); |
| |
| IndexWriter writer = new IndexWriter(directory, conf); |
| try |
| { |
| Documents.Document d = new Documents.Document(); |
| d.Add(NewTextField("foo", "bar", Field.Store.YES)); |
| writer.AddDocument(d); |
| } |
| finally |
| { |
| writer.Dispose(); |
| } |
| |
| IndexReader reader = DirectoryReader.Open(directory); |
| try |
| { |
| IndexSearcher searcher = NewSearcher(reader); |
| |
| ScoreDoc[] hits = searcher.Search(q, null, 1000).ScoreDocs; |
| Assert.AreEqual(1, hits.Length); |
| Assert.IsTrue(hits[0].Score < 0, "score is not negative: " + hits[0].Score); |
| |
| Explanation explain = searcher.Explain(q, hits[0].Doc); |
| Assert.AreEqual(hits[0].Score, explain.Value, 0.001f, "score doesn't match explanation"); |
| Assert.IsTrue(explain.IsMatch, "explain doesn't think doc is a match"); |
| |
| } |
| finally |
| { |
| reader.Dispose(); |
| } |
| } |
| finally |
| { |
| directory.Dispose(); |
| } |
| |
| } |
| |
| /// <summary> |
| /// this test performs a number of searches. It also compares output |
| /// of searches using multi-file index segments with single-file |
| /// index segments. |
| /// |
| /// TODO: someone should check that the results of the searches are |
| /// still correct by adding assert statements. Right now, the test |
| /// passes if the results are the same between multi-file and |
| /// single-file formats, even if the results are wrong. |
| /// </summary> |
| [Test] |
| public virtual void TestSearch() |
| { |
| StringWriter sw; |
| string multiFileOutput; |
| string singleFileOutput; |
| using (sw = new StringWriter()) |
| { |
| DoTestSearch(Random, sw, false); |
| multiFileOutput = sw.ToString(); |
| } |
| |
| //System.out.println(multiFileOutput); |
| |
| using (sw = new StringWriter()) |
| { |
| DoTestSearch(Random, sw, true); |
| singleFileOutput = sw.ToString(); |
| } |
| |
| Assert.AreEqual(multiFileOutput, singleFileOutput); |
| } |
| |
| |
| private void DoTestSearch(Random random, StringWriter @out, bool useCompoundFile) |
| { |
| Store.Directory directory = NewDirectory(); |
| Analyzer analyzer = new MockAnalyzer(random); |
| IndexWriterConfig conf = NewIndexWriterConfig(TEST_VERSION_CURRENT, analyzer); |
| MergePolicy mp = conf.MergePolicy; |
| mp.NoCFSRatio = useCompoundFile ? 1.0 : 0.0; |
| IndexWriter writer = new IndexWriter(directory, conf); |
| |
| string[] docs = new string[] { "a b c d e", "a b c d e a b c d e", "a b c d e f g h i j", "a c e", "e c a", "a c e a c e", "a c e a b c" }; |
| for (int j = 0; j < docs.Length; j++) |
| { |
| Documents.Document d = new Documents.Document(); |
| d.Add(NewTextField("contents", docs[j], Field.Store.YES)); |
| d.Add(NewStringField("id", "" + j, Field.Store.NO)); |
| writer.AddDocument(d); |
| } |
| writer.Dispose(); |
| |
| IndexReader reader = DirectoryReader.Open(directory); |
| IndexSearcher searcher = NewSearcher(reader); |
| |
| ScoreDoc[] hits = null; |
| |
| Sort sort = new Sort(SortField.FIELD_SCORE, new SortField("id", SortFieldType.INT32)); |
| |
| foreach (Query query in BuildQueries()) |
| { |
| @out.WriteLine("Query: " + query.ToString("contents")); |
| if (Verbose) |
| { |
| Console.WriteLine("TEST: query=" + query); |
| } |
| |
| hits = searcher.Search(query, null, 1000, sort).ScoreDocs; |
| |
| @out.WriteLine(hits.Length + " total results"); |
| for (int i = 0; i < hits.Length && i < 10; i++) |
| { |
| Documents.Document d = searcher.Doc(hits[i].Doc); |
| @out.WriteLine(i + " " + hits[i].Score + " " + d.Get("contents")); |
| } |
| } |
| reader.Dispose(); |
| directory.Dispose(); |
| } |
| |
| private IList<Query> BuildQueries() |
| { |
| IList<Query> queries = new List<Query>(); |
| |
| BooleanQuery booleanAB = new BooleanQuery(); |
| booleanAB.Add(new TermQuery(new Term("contents", "a")), Occur.SHOULD); |
| booleanAB.Add(new TermQuery(new Term("contents", "b")), Occur.SHOULD); |
| queries.Add(booleanAB); |
| |
| PhraseQuery phraseAB = new PhraseQuery(); |
| phraseAB.Add(new Term("contents", "a")); |
| phraseAB.Add(new Term("contents", "b")); |
| queries.Add(phraseAB); |
| |
| PhraseQuery phraseABC = new PhraseQuery(); |
| phraseABC.Add(new Term("contents", "a")); |
| phraseABC.Add(new Term("contents", "b")); |
| phraseABC.Add(new Term("contents", "c")); |
| queries.Add(phraseABC); |
| |
| BooleanQuery booleanAC = new BooleanQuery(); |
| booleanAC.Add(new TermQuery(new Term("contents", "a")), Occur.SHOULD); |
| booleanAC.Add(new TermQuery(new Term("contents", "c")), Occur.SHOULD); |
| queries.Add(booleanAC); |
| |
| PhraseQuery phraseAC = new PhraseQuery(); |
| phraseAC.Add(new Term("contents", "a")); |
| phraseAC.Add(new Term("contents", "c")); |
| queries.Add(phraseAC); |
| |
| PhraseQuery phraseACE = new PhraseQuery(); |
| phraseACE.Add(new Term("contents", "a")); |
| phraseACE.Add(new Term("contents", "c")); |
| phraseACE.Add(new Term("contents", "e")); |
| queries.Add(phraseACE); |
| |
| return queries; |
| } |
| } |
| } |