270 lines
9.0 KiB
C#
270 lines
9.0 KiB
C#
|
/*
|
||
|
* 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 WhitespaceAnalyzer = Lucene.Net.Analysis.WhitespaceAnalyzer;
|
||
|
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 ParseException = Lucene.Net.QueryParsers.ParseException;
|
||
|
using QueryParser = Lucene.Net.QueryParsers.QueryParser;
|
||
|
using RAMDirectory = Lucene.Net.Store.RAMDirectory;
|
||
|
using SpanFirstQuery = Lucene.Net.Search.Spans.SpanFirstQuery;
|
||
|
using SpanNearQuery = Lucene.Net.Search.Spans.SpanNearQuery;
|
||
|
using SpanNotQuery = Lucene.Net.Search.Spans.SpanNotQuery;
|
||
|
using SpanOrQuery = Lucene.Net.Search.Spans.SpanOrQuery;
|
||
|
using SpanQuery = Lucene.Net.Search.Spans.SpanQuery;
|
||
|
using SpanTermQuery = Lucene.Net.Search.Spans.SpanTermQuery;
|
||
|
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
|
||
|
|
||
|
namespace Lucene.Net.Search
|
||
|
{
|
||
|
|
||
|
/// <summary> Tests primitive queries (ie: that rewrite to themselves) to
|
||
|
/// insure they match the expected set of docs, and that the score of each
|
||
|
/// match is equal to the value of the scores explanation.
|
||
|
///
|
||
|
/// <p/>
|
||
|
/// The assumption is that if all of the "primitive" queries work well,
|
||
|
/// then anything that rewrites to a primitive will work well also.
|
||
|
///
|
||
|
/// </summary>
|
||
|
/// <seealso cref="Subclasses for actual tests">
|
||
|
/// </seealso>
|
||
|
[TestFixture]
|
||
|
public class TestExplanations:LuceneTestCase
|
||
|
{
|
||
|
protected internal IndexSearcher searcher;
|
||
|
|
||
|
public const System.String KEY = "KEY";
|
||
|
public const System.String FIELD = "field";
|
||
|
public static readonly QueryParser qp = new QueryParser(Util.Version.LUCENE_CURRENT, FIELD, new WhitespaceAnalyzer());
|
||
|
|
||
|
[TearDown]
|
||
|
public override void TearDown()
|
||
|
{
|
||
|
searcher.Close();
|
||
|
searcher = null;
|
||
|
GC.Collect();
|
||
|
base.TearDown();
|
||
|
}
|
||
|
|
||
|
[SetUp]
|
||
|
public override void SetUp()
|
||
|
{
|
||
|
base.SetUp();
|
||
|
RAMDirectory directory = new RAMDirectory();
|
||
|
IndexWriter writer = new IndexWriter(directory, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
||
|
for (int i = 0; i < docFields.Length; i++)
|
||
|
{
|
||
|
Document doc = new Document();
|
||
|
doc.Add(new Field(KEY, "" + i, Field.Store.NO, Field.Index.NOT_ANALYZED));
|
||
|
doc.Add(new Field(FIELD, docFields[i], Field.Store.NO, Field.Index.ANALYZED));
|
||
|
writer.AddDocument(doc);
|
||
|
}
|
||
|
writer.Close();
|
||
|
searcher = new IndexSearcher(directory, true);
|
||
|
}
|
||
|
|
||
|
protected internal System.String[] docFields = new System.String[]{"w1 w2 w3 w4 w5", "w1 w3 w2 w3 zz", "w1 xx w2 yy w3", "w1 w3 xx w2 yy w3 zz"};
|
||
|
|
||
|
public virtual Query MakeQuery(System.String queryText)
|
||
|
{
|
||
|
return qp.Parse(queryText);
|
||
|
}
|
||
|
|
||
|
/// <summary>check the expDocNrs first, then check the query (and the explanations) </summary>
|
||
|
public virtual void Qtest(System.String queryText, int[] expDocNrs)
|
||
|
{
|
||
|
Qtest(MakeQuery(queryText), expDocNrs);
|
||
|
}
|
||
|
|
||
|
/// <summary>check the expDocNrs first, then check the query (and the explanations) </summary>
|
||
|
public virtual void Qtest(Query q, int[] expDocNrs)
|
||
|
{
|
||
|
CheckHits.CheckHitCollector(q, FIELD, searcher, expDocNrs);
|
||
|
}
|
||
|
|
||
|
/// <summary> Tests a query using qtest after wrapping it with both optB and reqB</summary>
|
||
|
/// <seealso cref="qtest">
|
||
|
/// </seealso>
|
||
|
/// <seealso cref="reqB">
|
||
|
/// </seealso>
|
||
|
/// <seealso cref="optB">
|
||
|
/// </seealso>
|
||
|
public virtual void Bqtest(Query q, int[] expDocNrs)
|
||
|
{
|
||
|
Qtest(ReqB(q), expDocNrs);
|
||
|
Qtest(OptB(q), expDocNrs);
|
||
|
}
|
||
|
/// <summary> Tests a query using qtest after wrapping it with both optB and reqB</summary>
|
||
|
/// <seealso cref="qtest">
|
||
|
/// </seealso>
|
||
|
/// <seealso cref="reqB">
|
||
|
/// </seealso>
|
||
|
/// <seealso cref="optB">
|
||
|
/// </seealso>
|
||
|
public virtual void Bqtest(System.String queryText, int[] expDocNrs)
|
||
|
{
|
||
|
Bqtest(MakeQuery(queryText), expDocNrs);
|
||
|
}
|
||
|
|
||
|
/// <summary> Convenience subclass of FieldCacheTermsFilter</summary>
|
||
|
[Serializable]
|
||
|
public class ItemizedFilter:FieldCacheTermsFilter
|
||
|
{
|
||
|
private static System.String[] int2str(int[] terms)
|
||
|
{
|
||
|
System.String[] out_Renamed = new System.String[terms.Length];
|
||
|
for (int i = 0; i < terms.Length; i++)
|
||
|
{
|
||
|
out_Renamed[i] = "" + terms[i];
|
||
|
}
|
||
|
return out_Renamed;
|
||
|
}
|
||
|
public ItemizedFilter(System.String keyField, int[] keys):base(keyField, int2str(keys))
|
||
|
{
|
||
|
}
|
||
|
public ItemizedFilter(int[] keys):base(Lucene.Net.Search.TestExplanations.KEY, int2str(keys))
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>helper for generating MultiPhraseQueries </summary>
|
||
|
public static Term[] Ta(System.String[] s)
|
||
|
{
|
||
|
Term[] t = new Term[s.Length];
|
||
|
for (int i = 0; i < s.Length; i++)
|
||
|
{
|
||
|
t[i] = new Term(FIELD, s[i]);
|
||
|
}
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
/// <summary>MACRO for SpanTermQuery </summary>
|
||
|
public virtual SpanTermQuery St(System.String s)
|
||
|
{
|
||
|
return new SpanTermQuery(new Term(FIELD, s));
|
||
|
}
|
||
|
|
||
|
/// <summary>MACRO for SpanNotQuery </summary>
|
||
|
public virtual SpanNotQuery Snot(SpanQuery i, SpanQuery e)
|
||
|
{
|
||
|
return new SpanNotQuery(i, e);
|
||
|
}
|
||
|
|
||
|
/// <summary>MACRO for SpanOrQuery containing two SpanTerm queries </summary>
|
||
|
public virtual SpanOrQuery Sor(System.String s, System.String e)
|
||
|
{
|
||
|
return Sor(St(s), St(e));
|
||
|
}
|
||
|
/// <summary>MACRO for SpanOrQuery containing two SpanQueries </summary>
|
||
|
public virtual SpanOrQuery Sor(SpanQuery s, SpanQuery e)
|
||
|
{
|
||
|
return new SpanOrQuery(new SpanQuery[]{s, e});
|
||
|
}
|
||
|
|
||
|
/// <summary>MACRO for SpanOrQuery containing three SpanTerm queries </summary>
|
||
|
public virtual SpanOrQuery Sor(System.String s, System.String m, System.String e)
|
||
|
{
|
||
|
return Sor(St(s), St(m), St(e));
|
||
|
}
|
||
|
/// <summary>MACRO for SpanOrQuery containing two SpanQueries </summary>
|
||
|
public virtual SpanOrQuery Sor(SpanQuery s, SpanQuery m, SpanQuery e)
|
||
|
{
|
||
|
return new SpanOrQuery(new SpanQuery[]{s, m, e});
|
||
|
}
|
||
|
|
||
|
/// <summary>MACRO for SpanNearQuery containing two SpanTerm queries </summary>
|
||
|
public virtual SpanNearQuery Snear(System.String s, System.String e, int slop, bool inOrder)
|
||
|
{
|
||
|
return Snear(St(s), St(e), slop, inOrder);
|
||
|
}
|
||
|
/// <summary>MACRO for SpanNearQuery containing two SpanQueries </summary>
|
||
|
public virtual SpanNearQuery Snear(SpanQuery s, SpanQuery e, int slop, bool inOrder)
|
||
|
{
|
||
|
return new SpanNearQuery(new SpanQuery[]{s, e}, slop, inOrder);
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>MACRO for SpanNearQuery containing three SpanTerm queries </summary>
|
||
|
public virtual SpanNearQuery Snear(System.String s, System.String m, System.String e, int slop, bool inOrder)
|
||
|
{
|
||
|
return Snear(St(s), St(m), St(e), slop, inOrder);
|
||
|
}
|
||
|
/// <summary>MACRO for SpanNearQuery containing three SpanQueries </summary>
|
||
|
public virtual SpanNearQuery Snear(SpanQuery s, SpanQuery m, SpanQuery e, int slop, bool inOrder)
|
||
|
{
|
||
|
return new SpanNearQuery(new SpanQuery[]{s, m, e}, slop, inOrder);
|
||
|
}
|
||
|
|
||
|
/// <summary>MACRO for SpanFirst(SpanTermQuery) </summary>
|
||
|
public virtual SpanFirstQuery Sf(System.String s, int b)
|
||
|
{
|
||
|
return new SpanFirstQuery(St(s), b);
|
||
|
}
|
||
|
|
||
|
/// <summary> MACRO: Wraps a Query in a BooleanQuery so that it is optional, along
|
||
|
/// with a second prohibited clause which will never match anything
|
||
|
/// </summary>
|
||
|
public virtual Query OptB(System.String q)
|
||
|
{
|
||
|
return OptB(MakeQuery(q));
|
||
|
}
|
||
|
/// <summary> MACRO: Wraps a Query in a BooleanQuery so that it is optional, along
|
||
|
/// with a second prohibited clause which will never match anything
|
||
|
/// </summary>
|
||
|
public virtual Query OptB(Query q)
|
||
|
{
|
||
|
BooleanQuery bq = new BooleanQuery(true);
|
||
|
bq.Add(q, Occur.SHOULD);
|
||
|
bq.Add(new TermQuery(new Term("NEVER", "MATCH")), Occur.MUST_NOT);
|
||
|
return bq;
|
||
|
}
|
||
|
|
||
|
/// <summary> MACRO: Wraps a Query in a BooleanQuery so that it is required, along
|
||
|
/// with a second optional clause which will match everything
|
||
|
/// </summary>
|
||
|
public virtual Query ReqB(System.String q)
|
||
|
{
|
||
|
return ReqB(MakeQuery(q));
|
||
|
}
|
||
|
/// <summary> MACRO: Wraps a Query in a BooleanQuery so that it is required, along
|
||
|
/// with a second optional clause which will match everything
|
||
|
/// </summary>
|
||
|
public virtual Query ReqB(Query q)
|
||
|
{
|
||
|
BooleanQuery bq = new BooleanQuery(true);
|
||
|
bq.Add(q, Occur.MUST);
|
||
|
bq.Add(new TermQuery(new Term(FIELD, "w1")), Occur.SHOULD);
|
||
|
return bq;
|
||
|
}
|
||
|
|
||
|
/// <summary> Placeholder: JUnit freaks if you don't have one test ... making
|
||
|
/// class abstract doesn't help
|
||
|
/// </summary>
|
||
|
[Test]
|
||
|
public virtual void TestNoop()
|
||
|
{
|
||
|
/* NOOP */
|
||
|
}
|
||
|
}
|
||
|
}
|