blob: 6f96ce5f852ca1ff93392e6ac2e77d2875ddd2ed [file] [log] [blame]
/*
* 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 System;
using NUnit.Framework;
using StandardAnalyzer = Lucene.Net.Analysis.Standard.StandardAnalyzer;
using Document = Lucene.Net.Documents.Document;
using Field = Lucene.Net.Documents.Field;
using IndexWriter = Lucene.Net.Index.IndexWriter;
using Term = Lucene.Net.Index.Term;
using QueryParser = Lucene.Net.QueryParsers.QueryParser;
using Directory = Lucene.Net.Store.Directory;
using MockRAMDirectory = Lucene.Net.Store.MockRAMDirectory;
using SpanNearQuery = Lucene.Net.Search.Spans.SpanNearQuery;
using SpanQuery = Lucene.Net.Search.Spans.SpanQuery;
using SpanTermQuery = Lucene.Net.Search.Spans.SpanTermQuery;
namespace Lucene.Net.Search
{
/// <summary> TestExplanations subclass focusing on basic query types</summary>
[TestFixture]
public class TestSimpleExplanations:TestExplanations
{
// we focus on queries that don't rewrite to other queries.
// if we get those covered well, then the ones that rewrite should
// also be covered.
/* simple term tests */
[Test]
public virtual void TestT1()
{
Qtest("w1", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestT2()
{
Qtest("w1^1000", new int[]{0, 1, 2, 3});
}
/* MatchAllDocs */
[Test]
public virtual void TestMA1()
{
Qtest(new MatchAllDocsQuery(), new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestMA2()
{
Query q = new MatchAllDocsQuery();
q.Boost = 1000;
Qtest(q, new int[]{0, 1, 2, 3});
}
/* some simple phrase tests */
[Test]
public virtual void TestP1()
{
Qtest("\"w1 w2\"", new int[]{0});
}
[Test]
public virtual void TestP2()
{
Qtest("\"w1 w3\"", new int[]{1, 3});
}
[Test]
public virtual void TestP3()
{
Qtest("\"w1 w2\"~1", new int[]{0, 1, 2});
}
[Test]
public virtual void TestP4()
{
Qtest("\"w2 w3\"~1", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestP5()
{
Qtest("\"w3 w2\"~1", new int[]{1, 3});
}
[Test]
public virtual void TestP6()
{
Qtest("\"w3 w2\"~2", new int[]{0, 1, 3});
}
[Test]
public virtual void TestP7()
{
Qtest("\"w3 w2\"~3", new int[]{0, 1, 2, 3});
}
/* some simple filtered query tests */
[Test]
public virtual void TestFQ1()
{
Qtest(new FilteredQuery(qp.Parse("w1"), new ItemizedFilter(new int[]{0, 1, 2, 3})), new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestFQ2()
{
Qtest(new FilteredQuery(qp.Parse("w1"), new ItemizedFilter(new int[]{0, 2, 3})), new int[]{0, 2, 3});
}
[Test]
public virtual void TestFQ3()
{
Qtest(new FilteredQuery(qp.Parse("xx"), new ItemizedFilter(new int[]{1, 3})), new int[]{3});
}
[Test]
public virtual void TestFQ4()
{
Qtest(new FilteredQuery(qp.Parse("xx^1000"), new ItemizedFilter(new int[]{1, 3})), new int[]{3});
}
[Test]
public virtual void TestFQ6()
{
Query q = new FilteredQuery(qp.Parse("xx"), new ItemizedFilter(new int[]{1, 3}));
q.Boost = 1000;
Qtest(q, new int[]{3});
}
/* ConstantScoreQueries */
[Test]
public virtual void TestCSQ1()
{
Query q = new ConstantScoreQuery(new ItemizedFilter(new int[]{0, 1, 2, 3}));
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestCSQ2()
{
Query q = new ConstantScoreQuery(new ItemizedFilter(new int[]{1, 3}));
Qtest(q, new int[]{1, 3});
}
[Test]
public virtual void TestCSQ3()
{
Query q = new ConstantScoreQuery(new ItemizedFilter(new int[]{0, 2}));
q.Boost = 1000;
Qtest(q, new int[]{0, 2});
}
/* DisjunctionMaxQuery */
[Test]
public virtual void TestDMQ1()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.0f);
q.Add(qp.Parse("w1"));
q.Add(qp.Parse("w5"));
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestDMQ2()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("w1"));
q.Add(qp.Parse("w5"));
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestDMQ3()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("QQ"));
q.Add(qp.Parse("w5"));
Qtest(q, new int[]{0});
}
[Test]
public virtual void TestDMQ4()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("QQ"));
q.Add(qp.Parse("xx"));
Qtest(q, new int[]{2, 3});
}
[Test]
public virtual void TestDMQ5()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("yy -QQ"));
q.Add(qp.Parse("xx"));
Qtest(q, new int[]{2, 3});
}
[Test]
public virtual void TestDMQ6()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("-yy w3"));
q.Add(qp.Parse("xx"));
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestDMQ7()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("-yy w3"));
q.Add(qp.Parse("w2"));
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestDMQ8()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("yy w5^100"));
q.Add(qp.Parse("xx^100000"));
Qtest(q, new int[]{0, 2, 3});
}
[Test]
public virtual void TestDMQ9()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
q.Add(qp.Parse("yy w5^100"));
q.Add(qp.Parse("xx^0"));
Qtest(q, new int[]{0, 2, 3});
}
/* MultiPhraseQuery */
[Test]
public virtual void TestMPQ1()
{
MultiPhraseQuery q = new MultiPhraseQuery();
q.Add(Ta(new System.String[]{"w1"}));
q.Add(Ta(new System.String[]{"w2", "w3", "xx"}));
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestMPQ2()
{
MultiPhraseQuery q = new MultiPhraseQuery();
q.Add(Ta(new System.String[]{"w1"}));
q.Add(Ta(new System.String[]{"w2", "w3"}));
Qtest(q, new int[]{0, 1, 3});
}
[Test]
public virtual void TestMPQ3()
{
MultiPhraseQuery q = new MultiPhraseQuery();
q.Add(Ta(new System.String[]{"w1", "xx"}));
q.Add(Ta(new System.String[]{"w2", "w3"}));
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestMPQ4()
{
MultiPhraseQuery q = new MultiPhraseQuery();
q.Add(Ta(new System.String[]{"w1"}));
q.Add(Ta(new System.String[]{"w2"}));
Qtest(q, new int[]{0});
}
[Test]
public virtual void TestMPQ5()
{
MultiPhraseQuery q = new MultiPhraseQuery();
q.Add(Ta(new System.String[]{"w1"}));
q.Add(Ta(new System.String[]{"w2"}));
q.Slop = 1;
Qtest(q, new int[]{0, 1, 2});
}
[Test]
public virtual void TestMPQ6()
{
MultiPhraseQuery q = new MultiPhraseQuery();
q.Add(Ta(new System.String[]{"w1", "w3"}));
q.Add(Ta(new System.String[]{"w2"}));
q.Slop = 1;
Qtest(q, new int[]{0, 1, 2, 3});
}
/* some simple tests of boolean queries containing term queries */
[Test]
public virtual void TestBQ1()
{
Qtest("+w1 +w2", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ2()
{
Qtest("+yy +w3", new int[]{2, 3});
}
[Test]
public virtual void TestBQ3()
{
Qtest("yy +w3", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ4()
{
Qtest("w1 (-xx w2)", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ5()
{
Qtest("w1 (+qq w2)", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ6()
{
Qtest("w1 -(-qq w5)", new int[]{1, 2, 3});
}
[Test]
public virtual void TestBQ7()
{
Qtest("+w1 +(qq (xx -w2) (+w3 +w4))", new int[]{0});
}
[Test]
public virtual void TestBQ8()
{
Qtest("+w1 (qq (xx -w2) (+w3 +w4))", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ9()
{
Qtest("+w1 (qq (-xx w2) -(+w3 +w4))", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ10()
{
Qtest("+w1 +(qq (-xx w2) -(+w3 +w4))", new int[]{1});
}
[Test]
public virtual void TestBQ11()
{
Qtest("w1 w2^1000.0", new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ14()
{
BooleanQuery q = new BooleanQuery(true);
q.Add(qp.Parse("QQQQQ"), Occur.SHOULD);
q.Add(qp.Parse("w1"), Occur.SHOULD);
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ15()
{
BooleanQuery q = new BooleanQuery(true);
q.Add(qp.Parse("QQQQQ"), Occur.MUST_NOT);
q.Add(qp.Parse("w1"), Occur.SHOULD);
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ16()
{
BooleanQuery q = new BooleanQuery(true);
q.Add(qp.Parse("QQQQQ"), Occur.SHOULD);
q.Add(qp.Parse("w1 -xx"), Occur.SHOULD);
Qtest(q, new int[]{0, 1});
}
[Test]
public virtual void TestBQ17()
{
BooleanQuery q = new BooleanQuery(true);
q.Add(qp.Parse("w2"), Occur.SHOULD);
q.Add(qp.Parse("w1 -xx"), Occur.SHOULD);
Qtest(q, new int[]{0, 1, 2, 3});
}
[Test]
public virtual void TestBQ19()
{
Qtest("-yy w3", new int[]{0, 1});
}
[Test]
public virtual void TestBQ20()
{
BooleanQuery q = new BooleanQuery();
q.MinimumNumberShouldMatch = 2;
q.Add(qp.Parse("QQQQQ"), Occur.SHOULD);
q.Add(qp.Parse("yy"), Occur.SHOULD);
q.Add(qp.Parse("zz"), Occur.SHOULD);
q.Add(qp.Parse("w5"), Occur.SHOULD);
q.Add(qp.Parse("w4"), Occur.SHOULD);
Qtest(q, new int[]{0, 3});
}
[Test]
public virtual void TestTermQueryMultiSearcherExplain()
{
// creating two directories for indices
Directory indexStoreA = new MockRAMDirectory();
Directory indexStoreB = new MockRAMDirectory();
Document lDoc = new Document();
lDoc.Add(new Field("handle", "1 2", Field.Store.YES, Field.Index.ANALYZED));
Document lDoc2 = new Document();
lDoc2.Add(new Field("handle", "1 2", Field.Store.YES, Field.Index.ANALYZED));
Document lDoc3 = new Document();
lDoc3.Add(new Field("handle", "1 2", Field.Store.YES, Field.Index.ANALYZED));
IndexWriter writerA = new IndexWriter(indexStoreA, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
IndexWriter writerB = new IndexWriter(indexStoreB, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
writerA.AddDocument(lDoc);
writerA.AddDocument(lDoc2);
writerA.Optimize();
writerA.Close();
writerB.AddDocument(lDoc3);
writerB.Close();
QueryParser parser = new QueryParser(Util.Version.LUCENE_CURRENT, "fulltext", new StandardAnalyzer(Util.Version.LUCENE_CURRENT));
Query query = parser.Parse("handle:1");
Searcher[] searchers = new Searcher[2];
searchers[0] = new IndexSearcher(indexStoreB, true);
searchers[1] = new IndexSearcher(indexStoreA, true);
Searcher mSearcher = new MultiSearcher(searchers);
ScoreDoc[] hits = mSearcher.Search(query, null, 1000).ScoreDocs;
Assert.AreEqual(3, hits.Length);
Explanation explain = mSearcher.Explain(query, hits[0].Doc);
System.String exp = explain.ToString(0);
Assert.IsTrue(exp.IndexOf("maxDocs=3") > - 1, exp);
Assert.IsTrue(exp.IndexOf("docFreq=3") > - 1, exp);
query = parser.Parse("handle:\"1 2\"");
hits = mSearcher.Search(query, null, 1000).ScoreDocs;
Assert.AreEqual(3, hits.Length);
explain = mSearcher.Explain(query, hits[0].Doc);
exp = explain.ToString(0);
Assert.IsTrue(exp.IndexOf("1=3") > - 1, exp);
Assert.IsTrue(exp.IndexOf("2=3") > - 1, exp);
query = new SpanNearQuery(new SpanQuery[]{new SpanTermQuery(new Term("handle", "1")), new SpanTermQuery(new Term("handle", "2"))}, 0, true);
hits = mSearcher.Search(query, null, 1000).ScoreDocs;
Assert.AreEqual(3, hits.Length);
explain = mSearcher.Explain(query, hits[0].Doc);
exp = explain.ToString(0);
Assert.IsTrue(exp.IndexOf("1=3") > - 1, exp);
Assert.IsTrue(exp.IndexOf("2=3") > - 1, exp);
mSearcher.Close();
}
}
}