blob: a85f8f16c8fe1a7b53c58d840878a2431e181b87 [file] [log] [blame]
using Lucene.Net.Search.Spans;
using NUnit.Framework;
namespace Lucene.Net.Search
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using DefaultSimilarity = Lucene.Net.Search.Similarities.DefaultSimilarity;
using Term = Lucene.Net.Index.Term;
/// <summary>
/// TestExplanations subclass that builds up super crazy complex queries
/// on the assumption that if the explanations work out right for them,
/// they should work for anything.
/// </summary>
[TestFixture]
public class TestComplexExplanations : TestExplanations
{
/// <summary>
/// Override the Similarity used in our searcher with one that plays
/// nice with boosts of 0.0
/// </summary>
[SetUp]
public override void SetUp()
{
base.SetUp();
searcher.Similarity = CreateQnorm1Similarity();
}
[TearDown]
public override void TearDown()
{
searcher.Similarity = IndexSearcher.DefaultSimilarity;
base.TearDown();
}
// must be static for weight serialization tests
private static DefaultSimilarity CreateQnorm1Similarity()
{
return new DefaultSimilarityAnonymousClass();
}
private class DefaultSimilarityAnonymousClass : DefaultSimilarity
{
public DefaultSimilarityAnonymousClass()
{
}
public override float QueryNorm(float sumOfSquaredWeights)
{
return 1.0f; // / (float) Math.sqrt(1.0f + sumOfSquaredWeights);
}
}
[Test]
public virtual void Test1()
{
BooleanQuery q = new BooleanQuery();
PhraseQuery phraseQuery = new PhraseQuery();
phraseQuery.Slop = 1;
phraseQuery.Add(new Term(FIELD, "w1"));
phraseQuery.Add(new Term(FIELD, "w2"));
q.Add(phraseQuery, Occur.MUST);
q.Add(Snear(St("w2"), Sor("w5", "zz"), 4, true), Occur.SHOULD);
q.Add(Snear(Sf("w3", 2), St("w2"), St("w3"), 5, true), Occur.SHOULD);
Query t = new FilteredQuery(new TermQuery(new Term(FIELD, "xx")), new ItemizedFilter(new int[] { 1, 3 }));
t.Boost = 1000;
q.Add(t, Occur.SHOULD);
t = new ConstantScoreQuery(new ItemizedFilter(new int[] { 0, 2 }));
t.Boost = 30;
q.Add(t, Occur.SHOULD);
DisjunctionMaxQuery dm = new DisjunctionMaxQuery(0.2f);
dm.Add(Snear(St("w2"), Sor("w5", "zz"), 4, true));
dm.Add(new TermQuery(new Term(FIELD, "QQ")));
BooleanQuery xxYYZZ = new BooleanQuery();
xxYYZZ.Add(new TermQuery(new Term(FIELD, "xx")), Occur.SHOULD);
xxYYZZ.Add(new TermQuery(new Term(FIELD, "yy")), Occur.SHOULD);
xxYYZZ.Add(new TermQuery(new Term(FIELD, "zz")), Occur.MUST_NOT);
dm.Add(xxYYZZ);
BooleanQuery xxW1 = new BooleanQuery();
xxW1.Add(new TermQuery(new Term(FIELD, "xx")), Occur.MUST_NOT);
xxW1.Add(new TermQuery(new Term(FIELD, "w1")), Occur.MUST_NOT);
dm.Add(xxW1);
DisjunctionMaxQuery dm2 = new DisjunctionMaxQuery(0.5f);
dm2.Add(new TermQuery(new Term(FIELD, "w1")));
dm2.Add(new TermQuery(new Term(FIELD, "w2")));
dm2.Add(new TermQuery(new Term(FIELD, "w3")));
dm.Add(dm2);
q.Add(dm, Occur.SHOULD);
BooleanQuery b = new BooleanQuery();
b.MinimumNumberShouldMatch = 2;
b.Add(Snear("w1", "w2", 1, true), Occur.SHOULD);
b.Add(Snear("w2", "w3", 1, true), Occur.SHOULD);
b.Add(Snear("w1", "w3", 3, true), Occur.SHOULD);
q.Add(b, Occur.SHOULD);
Qtest(q, new int[] { 0, 1, 2 });
}
[Test]
public virtual void Test2()
{
BooleanQuery q = new BooleanQuery();
PhraseQuery phraseQuery = new PhraseQuery();
phraseQuery.Slop = 1;
phraseQuery.Add(new Term(FIELD, "w1"));
phraseQuery.Add(new Term(FIELD, "w2"));
q.Add(phraseQuery, Occur.MUST);
q.Add(Snear(St("w2"), Sor("w5", "zz"), 4, true), Occur.SHOULD);
q.Add(Snear(Sf("w3", 2), St("w2"), St("w3"), 5, true), Occur.SHOULD);
Query t = new FilteredQuery(new TermQuery(new Term(FIELD, "xx")), new ItemizedFilter(new int[] { 1, 3 }));
t.Boost = 1000;
q.Add(t, Occur.SHOULD);
t = new ConstantScoreQuery(new ItemizedFilter(new int[] { 0, 2 }));
t.Boost = -20.0f;
q.Add(t, Occur.SHOULD);
DisjunctionMaxQuery dm = new DisjunctionMaxQuery(0.2f);
dm.Add(Snear(St("w2"), Sor("w5", "zz"), 4, true));
dm.Add(new TermQuery(new Term(FIELD, "QQ")));
BooleanQuery xxYYZZ = new BooleanQuery();
xxYYZZ.Add(new TermQuery(new Term(FIELD, "xx")), Occur.SHOULD);
xxYYZZ.Add(new TermQuery(new Term(FIELD, "yy")), Occur.SHOULD);
xxYYZZ.Add(new TermQuery(new Term(FIELD, "zz")), Occur.MUST_NOT);
dm.Add(xxYYZZ);
BooleanQuery xxW1 = new BooleanQuery();
xxW1.Add(new TermQuery(new Term(FIELD, "xx")), Occur.MUST_NOT);
xxW1.Add(new TermQuery(new Term(FIELD, "w1")), Occur.MUST_NOT);
dm.Add(xxW1);
DisjunctionMaxQuery dm2 = new DisjunctionMaxQuery(0.5f);
dm2.Add(new TermQuery(new Term(FIELD, "w1")));
dm2.Add(new TermQuery(new Term(FIELD, "w2")));
dm2.Add(new TermQuery(new Term(FIELD, "w3")));
dm.Add(dm2);
q.Add(dm, Occur.SHOULD);
BooleanQuery b = new BooleanQuery();
b.MinimumNumberShouldMatch = 2;
b.Add(Snear("w1", "w2", 1, true), Occur.SHOULD);
b.Add(Snear("w2", "w3", 1, true), Occur.SHOULD);
b.Add(Snear("w1", "w3", 3, true), Occur.SHOULD);
b.Boost = 0.0f;
q.Add(b, Occur.SHOULD);
Qtest(q, new int[] { 0, 1, 2 });
}
// :TODO: we really need more crazy complex cases.
// //////////////////////////////////////////////////////////////////
// The rest of these aren't that complex, but they are <i>somewhat</i>
// complex, and they expose weakness in dealing with queries that match
// with scores of 0 wrapped in other queries
[Test]
public virtual void TestT3()
{
TermQuery query = new TermQuery(new Term(FIELD, "w1"));
query.Boost = 0;
Bqtest(query, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestMA3()
{
Query q = new MatchAllDocsQuery();
q.Boost = 0;
Bqtest(q, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestFQ5()
{
TermQuery query = new TermQuery(new Term(FIELD, "xx"));
query.Boost = 0;
Bqtest(new FilteredQuery(query, new ItemizedFilter(new int[] { 1, 3 })), new int[] { 3 });
}
[Test]
public virtual void TestCSQ4()
{
Query q = new ConstantScoreQuery(new ItemizedFilter(new int[] { 3 }));
q.Boost = 0;
Bqtest(q, new int[] { 3 });
}
[Test]
public virtual void TestDMQ10()
{
DisjunctionMaxQuery q = new DisjunctionMaxQuery(0.5f);
BooleanQuery query = new BooleanQuery();
query.Add(new TermQuery(new Term(FIELD, "yy")), Occur.SHOULD);
TermQuery boostedQuery = new TermQuery(new Term(FIELD, "w5"));
boostedQuery.Boost = 100;
query.Add(boostedQuery, Occur.SHOULD);
q.Add(query);
TermQuery xxBoostedQuery = new TermQuery(new Term(FIELD, "xx"));
xxBoostedQuery.Boost = 0;
q.Add(xxBoostedQuery);
q.Boost = 0.0f;
Bqtest(q, new int[] { 0, 2, 3 });
}
[Test]
public virtual void TestMPQ7()
{
MultiPhraseQuery q = new MultiPhraseQuery();
q.Add(Ta(new string[] { "w1" }));
q.Add(Ta(new string[] { "w2" }));
q.Slop = 1;
q.Boost = 0.0f;
Bqtest(q, new int[] { 0, 1, 2 });
}
[Test]
public virtual void TestBQ12()
{
// NOTE: using qtest not bqtest
BooleanQuery query = new BooleanQuery();
query.Add(new TermQuery(new Term(FIELD, "w1")), Occur.SHOULD);
TermQuery boostedQuery = new TermQuery(new Term(FIELD, "w2"));
boostedQuery.Boost = 0;
query.Add(boostedQuery, Occur.SHOULD);
Qtest(query, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestBQ13()
{
// NOTE: using qtest not bqtest
BooleanQuery query = new BooleanQuery();
query.Add(new TermQuery(new Term(FIELD, "w1")), Occur.SHOULD);
TermQuery boostedQuery = new TermQuery(new Term(FIELD, "w5"));
boostedQuery.Boost = 0;
query.Add(boostedQuery, Occur.MUST_NOT);
Qtest(query, new int[] { 1, 2, 3 });
}
[Test]
public virtual void TestBQ18()
{
// NOTE: using qtest not bqtest
BooleanQuery query = new BooleanQuery();
TermQuery boostedQuery = new TermQuery(new Term(FIELD, "w1"));
boostedQuery.Boost = 0;
query.Add(boostedQuery, Occur.MUST);
query.Add(new TermQuery(new Term(FIELD, "w2")), Occur.SHOULD);
Qtest(query, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestBQ21()
{
BooleanQuery query = new BooleanQuery();
query.Add(new TermQuery(new Term(FIELD, "w1")), Occur.MUST);
query.Add(new TermQuery(new Term(FIELD, "w2")), Occur.SHOULD);
query.Boost = 0;
Bqtest(query, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestBQ22()
{
BooleanQuery query = new BooleanQuery();
TermQuery boostedQuery = new TermQuery(new Term(FIELD, "w1"));
boostedQuery.Boost = 0;
query.Add(boostedQuery, Occur.MUST);
query.Add(new TermQuery(new Term(FIELD, "w2")), Occur.SHOULD);
query.Boost = 0;
Bqtest(query, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestST3()
{
SpanQuery q = St("w1");
q.Boost = 0;
Bqtest(q, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestST6()
{
SpanQuery q = St("xx");
q.Boost = 0;
Qtest(q, new int[] { 2, 3 });
}
[Test]
public virtual void TestSF3()
{
SpanQuery q = Sf(("w1"), 1);
q.Boost = 0;
Bqtest(q, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestSF7()
{
SpanQuery q = Sf(("xx"), 3);
q.Boost = 0;
Bqtest(q, new int[] { 2, 3 });
}
[Test]
public virtual void TestSNot3()
{
SpanQuery q = Snot(Sf("w1", 10), St("QQ"));
q.Boost = 0;
Bqtest(q, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestSNot6()
{
SpanQuery q = Snot(Sf("w1", 10), St("xx"));
q.Boost = 0;
Bqtest(q, new int[] { 0, 1, 2, 3 });
}
[Test]
public virtual void TestSNot8()
{
// NOTE: using qtest not bqtest
SpanQuery f = Snear("w1", "w3", 10, true);
f.Boost = 0;
SpanQuery q = Snot(f, St("xx"));
Qtest(q, new int[] { 0, 1, 3 });
}
[Test]
public virtual void TestSNot9()
{
// NOTE: using qtest not bqtest
SpanQuery t = St("xx");
t.Boost = 0;
SpanQuery q = Snot(Snear("w1", "w3", 10, true), t);
Qtest(q, new int[] { 0, 1, 3 });
}
}
}