1197 lines
49 KiB
C#
1197 lines
49 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 System.Collections.Generic;
|
|||
|
using Lucene.Net.Analysis.Tokenattributes;
|
|||
|
using Lucene.Net.Support;
|
|||
|
using NUnit.Framework;
|
|||
|
|
|||
|
using Analyzer = Lucene.Net.Analysis.Analyzer;
|
|||
|
using KeywordAnalyzer = Lucene.Net.Analysis.KeywordAnalyzer;
|
|||
|
using LowerCaseTokenizer = Lucene.Net.Analysis.LowerCaseTokenizer;
|
|||
|
using SimpleAnalyzer = Lucene.Net.Analysis.SimpleAnalyzer;
|
|||
|
using StopAnalyzer = Lucene.Net.Analysis.StopAnalyzer;
|
|||
|
using StopFilter = Lucene.Net.Analysis.StopFilter;
|
|||
|
using TokenFilter = Lucene.Net.Analysis.TokenFilter;
|
|||
|
using TokenStream = Lucene.Net.Analysis.TokenStream;
|
|||
|
using WhitespaceAnalyzer = Lucene.Net.Analysis.WhitespaceAnalyzer;
|
|||
|
using StandardAnalyzer = Lucene.Net.Analysis.Standard.StandardAnalyzer;
|
|||
|
using DateField = Lucene.Net.Documents.DateField;
|
|||
|
using DateTools = Lucene.Net.Documents.DateTools;
|
|||
|
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 IndexReader = Lucene.Net.Index.IndexReader;
|
|||
|
using RAMDirectory = Lucene.Net.Store.RAMDirectory;
|
|||
|
using BooleanQuery = Lucene.Net.Search.BooleanQuery;
|
|||
|
using FuzzyQuery = Lucene.Net.Search.FuzzyQuery;
|
|||
|
using IndexSearcher = Lucene.Net.Search.IndexSearcher;
|
|||
|
using MatchAllDocsQuery = Lucene.Net.Search.MatchAllDocsQuery;
|
|||
|
using MultiTermQuery = Lucene.Net.Search.MultiTermQuery;
|
|||
|
using PhraseQuery = Lucene.Net.Search.PhraseQuery;
|
|||
|
using PrefixQuery = Lucene.Net.Search.PrefixQuery;
|
|||
|
using Query = Lucene.Net.Search.Query;
|
|||
|
using ScoreDoc = Lucene.Net.Search.ScoreDoc;
|
|||
|
using TermQuery = Lucene.Net.Search.TermQuery;
|
|||
|
using TermRangeQuery = Lucene.Net.Search.TermRangeQuery;
|
|||
|
using WildcardQuery = Lucene.Net.Search.WildcardQuery;
|
|||
|
using Directory = Lucene.Net.Store.Directory;
|
|||
|
using MockRAMDirectory = Lucene.Net.Store.MockRAMDirectory;
|
|||
|
using LocalizedTestCase = Lucene.Net.Util.LocalizedTestCase;
|
|||
|
using Version = Lucene.Net.Util.Version;
|
|||
|
|
|||
|
namespace Lucene.Net.QueryParsers
|
|||
|
{
|
|||
|
|
|||
|
/// <summary> Tests QueryParser.</summary>
|
|||
|
[TestFixture]
|
|||
|
public class TestQueryParser:LocalizedTestCase
|
|||
|
{
|
|||
|
private static readonly HashSet<string> dataTestWithDifferentLocals = new HashSet<string>
|
|||
|
{
|
|||
|
"TestLegacyDateRange",
|
|||
|
"TestDateRange",
|
|||
|
"TestCJK",
|
|||
|
"TestNumber",
|
|||
|
"TestFarsiRangeCollating",
|
|||
|
"TestLocalDateFormat"
|
|||
|
};
|
|||
|
|
|||
|
private class AnonymousClassQueryParser : QueryParser
|
|||
|
{
|
|||
|
private void InitBlock(int[] type, TestQueryParser enclosingInstance)
|
|||
|
{
|
|||
|
this.type = type;
|
|||
|
this.enclosingInstance = enclosingInstance;
|
|||
|
}
|
|||
|
private int[] type;
|
|||
|
private TestQueryParser enclosingInstance;
|
|||
|
public TestQueryParser Enclosing_Instance
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return enclosingInstance;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
internal AnonymousClassQueryParser(int[] type, TestQueryParser enclosingInstance, System.String Param1, Lucene.Net.Analysis.Analyzer Param2)
|
|||
|
: base(Version.LUCENE_CURRENT, Param1, Param2)
|
|||
|
{
|
|||
|
InitBlock(type, enclosingInstance);
|
|||
|
}
|
|||
|
protected internal override Query GetWildcardQuery(System.String field, System.String termStr)
|
|||
|
{
|
|||
|
// override error checking of superclass
|
|||
|
type[0] = 1;
|
|||
|
return new TermQuery(new Term(field, termStr));
|
|||
|
}
|
|||
|
protected internal override Query GetPrefixQuery(System.String field, System.String termStr)
|
|||
|
{
|
|||
|
// override error checking of superclass
|
|||
|
type[0] = 2;
|
|||
|
return new TermQuery(new Term(field, termStr));
|
|||
|
}
|
|||
|
|
|||
|
protected internal override Query GetFieldQuery(System.String field, System.String queryText)
|
|||
|
{
|
|||
|
type[0] = 3;
|
|||
|
return base.GetFieldQuery(field, queryText);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public TestQueryParser(System.String name)
|
|||
|
: base(name, dataTestWithDifferentLocals) // TODO: was commented out
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public TestQueryParser() : base(string.Empty, dataTestWithDifferentLocals)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public static Analyzer qpAnalyzer = new QPTestAnalyzer();
|
|||
|
|
|||
|
public class QPTestFilter : TokenFilter
|
|||
|
{
|
|||
|
internal ITermAttribute termAtt;
|
|||
|
internal IOffsetAttribute offsetAtt;
|
|||
|
|
|||
|
/// <summary> Filter which discards the token 'stop' and which expands the
|
|||
|
/// token 'phrase' into 'phrase1 phrase2'
|
|||
|
/// </summary>
|
|||
|
public QPTestFilter(TokenStream in_Renamed):base(in_Renamed)
|
|||
|
{
|
|||
|
termAtt = AddAttribute<ITermAttribute>();
|
|||
|
offsetAtt = AddAttribute<IOffsetAttribute>();
|
|||
|
}
|
|||
|
|
|||
|
internal bool inPhrase = false;
|
|||
|
internal int savedStart = 0, savedEnd = 0;
|
|||
|
|
|||
|
public override bool IncrementToken()
|
|||
|
{
|
|||
|
if (inPhrase)
|
|||
|
{
|
|||
|
inPhrase = false;
|
|||
|
ClearAttributes();
|
|||
|
termAtt.SetTermBuffer("phrase2");
|
|||
|
offsetAtt.SetOffset(savedStart, savedEnd);
|
|||
|
return true;
|
|||
|
}
|
|||
|
else
|
|||
|
while (input.IncrementToken())
|
|||
|
{
|
|||
|
if (termAtt.Term.Equals("phrase"))
|
|||
|
{
|
|||
|
inPhrase = true;
|
|||
|
savedStart = offsetAtt.StartOffset;
|
|||
|
savedEnd = offsetAtt.EndOffset;
|
|||
|
termAtt.SetTermBuffer("phrase1");
|
|||
|
offsetAtt.SetOffset(savedStart, savedEnd);
|
|||
|
return true;
|
|||
|
}
|
|||
|
else if (!termAtt.Term.Equals("stop"))
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public class QPTestAnalyzer:Analyzer
|
|||
|
{
|
|||
|
|
|||
|
/// <summary>Filters LowerCaseTokenizer with StopFilter. </summary>
|
|||
|
public override TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader)
|
|||
|
{
|
|||
|
return new QPTestFilter(new LowerCaseTokenizer(reader));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class QPTestParser:QueryParser
|
|||
|
{
|
|||
|
public QPTestParser(System.String f, Analyzer a):base(Version.LUCENE_CURRENT, f, a)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
protected internal override Query GetFuzzyQuery(System.String field, System.String termStr, float minSimilarity)
|
|||
|
{
|
|||
|
throw new ParseException("Fuzzy queries not allowed");
|
|||
|
}
|
|||
|
|
|||
|
protected internal override Query GetWildcardQuery(System.String field, System.String termStr)
|
|||
|
{
|
|||
|
throw new ParseException("Wildcard queries not allowed");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private int originalMaxClauses;
|
|||
|
|
|||
|
[SetUp]
|
|||
|
public override void SetUp()
|
|||
|
{
|
|||
|
base.SetUp();
|
|||
|
originalMaxClauses = BooleanQuery.MaxClauseCount;
|
|||
|
}
|
|||
|
|
|||
|
public virtual QueryParser GetParser(Analyzer a)
|
|||
|
{
|
|||
|
if (a == null)
|
|||
|
a = new SimpleAnalyzer();
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", a);
|
|||
|
qp.DefaultOperator = QueryParser.OR_OPERATOR;
|
|||
|
return qp;
|
|||
|
}
|
|||
|
|
|||
|
public virtual Query GetQuery(System.String query, Analyzer a)
|
|||
|
{
|
|||
|
return GetParser(a).Parse(query);
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertQueryEquals(System.String query, Analyzer a, System.String result)
|
|||
|
{
|
|||
|
Query q = GetQuery(query, a);
|
|||
|
var s = q.ToString("field");
|
|||
|
Assert.AreEqual(s, result, "Query /" + query + "/ yielded /" + s + "/, expecting /" + result + "/");
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertQueryEquals(QueryParser qp, System.String field, System.String query, System.String result)
|
|||
|
{
|
|||
|
Query q = qp.Parse(query);
|
|||
|
System.String s = q.ToString(field);
|
|||
|
Assert.AreEqual(s, result, "Query /" + query + "/ yielded /" + s + "/, expecting /" + result + "/");
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertEscapedQueryEquals(System.String query, Analyzer a, System.String result)
|
|||
|
{
|
|||
|
System.String escapedQuery = QueryParser.Escape(query);
|
|||
|
Assert.AreEqual(escapedQuery, result, "Query /" + query + "/ yielded /" + escapedQuery + "/, expecting /" + result + "/");
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertWildcardQueryEquals(System.String query, bool lowercase, System.String result, bool allowLeadingWildcard)
|
|||
|
{
|
|||
|
QueryParser qp = GetParser(null);
|
|||
|
qp.LowercaseExpandedTerms = lowercase;
|
|||
|
qp.AllowLeadingWildcard = allowLeadingWildcard;
|
|||
|
Query q = qp.Parse(query);
|
|||
|
System.String s = q.ToString("field");
|
|||
|
Assert.AreEqual(s, result, "WildcardQuery /" + query + "/ yielded /" + s + "/, expecting /" + result + "/");
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertWildcardQueryEquals(System.String query, bool lowercase, System.String result)
|
|||
|
{
|
|||
|
AssertWildcardQueryEquals(query, lowercase, result, false);
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertWildcardQueryEquals(System.String query, System.String result)
|
|||
|
{
|
|||
|
QueryParser qp = GetParser(null);
|
|||
|
Query q = qp.Parse(query);
|
|||
|
System.String s = q.ToString("field");
|
|||
|
Assert.AreEqual(s, result, "WildcardQuery /" + query + "/ yielded /" + s + "/, expecting /" + result + "/");
|
|||
|
}
|
|||
|
|
|||
|
public virtual Query GetQueryDOA(System.String query, Analyzer a)
|
|||
|
{
|
|||
|
if (a == null)
|
|||
|
a = new SimpleAnalyzer();
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", a);
|
|||
|
qp.DefaultOperator = QueryParser.AND_OPERATOR;
|
|||
|
return qp.Parse(query);
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertQueryEqualsDOA(System.String query, Analyzer a, System.String result)
|
|||
|
{
|
|||
|
Query q = GetQueryDOA(query, a);
|
|||
|
System.String s = q.ToString("field");
|
|||
|
Assert.AreEqual(s, result, "Query /" + query + "/ yielded /" + s + "/, expecting /" + result + "/");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestCJK()
|
|||
|
{
|
|||
|
// Test Ideographic Space - As wide as a CJK character cell (fullwidth)
|
|||
|
// used google to translate the word "term" to japanese -> 用語
|
|||
|
//
|
|||
|
// NOTE: What is printed above is not the translation of "term" into
|
|||
|
// Japanese. Google translate currently gives:
|
|||
|
//
|
|||
|
// 期間
|
|||
|
//
|
|||
|
// Which translates to unicode characters 26399 and 38291, or
|
|||
|
// the literals '\u671f' and '\u9593'.
|
|||
|
//
|
|||
|
// Unlike the second and third characters in the previous string ('\u201d' and '\u00a8')
|
|||
|
// which fail the test for IsCharacter when tokenized by LetterTokenizer (as it should
|
|||
|
// in Java), which causes the word to be split differently than if it actually used
|
|||
|
// letters as defined by Unicode.
|
|||
|
//
|
|||
|
// Using the string "\u671f\u9593\u3000\u671f\u9593\u3000\u671f\u9593" with just the two
|
|||
|
// characters is enough, as it uses two characters with the full width of a CJK character cell.
|
|||
|
AssertQueryEquals("term\u3000term\u3000term", null, "term\u0020term\u0020term");
|
|||
|
AssertQueryEquals("\u671f\u9593\u3000\u671f\u9593\u3000\u671f\u9593", null, "\u671f\u9593\u0020\u671f\u9593\u0020\u671f\u9593");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestSimple()
|
|||
|
{
|
|||
|
AssertQueryEquals("term term term", null, "term term term");
|
|||
|
AssertQueryEquals("türm term term", new WhitespaceAnalyzer(), "türm term term");
|
|||
|
AssertQueryEquals("ümlaut", new WhitespaceAnalyzer(), "ümlaut");
|
|||
|
|
|||
|
AssertQueryEquals("\"\"", new KeywordAnalyzer(), "");
|
|||
|
AssertQueryEquals("foo:\"\"", new KeywordAnalyzer(), "foo:");
|
|||
|
|
|||
|
AssertQueryEquals("a AND b", null, "+a +b");
|
|||
|
AssertQueryEquals("(a AND b)", null, "+a +b");
|
|||
|
AssertQueryEquals("c OR (a AND b)", null, "c (+a +b)");
|
|||
|
AssertQueryEquals("a AND NOT b", null, "+a -b");
|
|||
|
AssertQueryEquals("a AND -b", null, "+a -b");
|
|||
|
AssertQueryEquals("a AND !b", null, "+a -b");
|
|||
|
AssertQueryEquals("a && b", null, "+a +b");
|
|||
|
AssertQueryEquals("a && ! b", null, "+a -b");
|
|||
|
|
|||
|
AssertQueryEquals("a OR b", null, "a b");
|
|||
|
AssertQueryEquals("a || b", null, "a b");
|
|||
|
AssertQueryEquals("a OR !b", null, "a -b");
|
|||
|
AssertQueryEquals("a OR ! b", null, "a -b");
|
|||
|
AssertQueryEquals("a OR -b", null, "a -b");
|
|||
|
|
|||
|
AssertQueryEquals("+term -term term", null, "+term -term term");
|
|||
|
AssertQueryEquals("foo:term AND field:anotherTerm", null, "+foo:term +anotherterm");
|
|||
|
AssertQueryEquals("term AND \"phrase phrase\"", null, "+term +\"phrase phrase\"");
|
|||
|
AssertQueryEquals("\"hello there\"", null, "\"hello there\"");
|
|||
|
Assert.IsTrue(GetQuery("a AND b", null) is BooleanQuery);
|
|||
|
Assert.IsTrue(GetQuery("hello", null) is TermQuery);
|
|||
|
Assert.IsTrue(GetQuery("\"hello there\"", null) is PhraseQuery);
|
|||
|
|
|||
|
AssertQueryEquals("germ term^2.0", null, "germ term^2.0");
|
|||
|
AssertQueryEquals("(term)^2.0", null, "term^2.0");
|
|||
|
AssertQueryEquals("(germ term)^2.0", null, "(germ term)^2.0");
|
|||
|
AssertQueryEquals("term^2.0", null, "term^2.0");
|
|||
|
AssertQueryEquals("term^2", null, "term^2.0");
|
|||
|
AssertQueryEquals("\"germ term\"^2.0", null, "\"germ term\"^2.0");
|
|||
|
AssertQueryEquals("\"term germ\"^2", null, "\"term germ\"^2.0");
|
|||
|
|
|||
|
AssertQueryEquals("(foo OR bar) AND (baz OR boo)", null, "+(foo bar) +(baz boo)");
|
|||
|
AssertQueryEquals("((a OR b) AND NOT c) OR d", null, "(+(a b) -c) d");
|
|||
|
AssertQueryEquals("+(apple \"steve jobs\") -(foo bar baz)", null, "+(apple \"steve jobs\") -(foo bar baz)");
|
|||
|
AssertQueryEquals("+title:(dog OR cat) -author:\"bob dole\"", null, "+(title:dog title:cat) -author:\"bob dole\"");
|
|||
|
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new StandardAnalyzer(Util.Version.LUCENE_CURRENT));
|
|||
|
// make sure OR is the default:
|
|||
|
Assert.AreEqual(QueryParser.OR_OPERATOR, qp.DefaultOperator);
|
|||
|
qp.DefaultOperator = QueryParser.AND_OPERATOR;
|
|||
|
Assert.AreEqual(QueryParser.AND_OPERATOR, qp.DefaultOperator);
|
|||
|
qp.DefaultOperator = QueryParser.OR_OPERATOR;
|
|||
|
Assert.AreEqual(QueryParser.OR_OPERATOR, qp.DefaultOperator);
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestPunct()
|
|||
|
{
|
|||
|
Analyzer a = new WhitespaceAnalyzer();
|
|||
|
AssertQueryEquals("a&b", a, "a&b");
|
|||
|
AssertQueryEquals("a&&b", a, "a&&b");
|
|||
|
AssertQueryEquals(".NET", a, ".NET");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestSlop()
|
|||
|
{
|
|||
|
AssertQueryEquals("\"term germ\"~2", null, "\"term germ\"~2");
|
|||
|
AssertQueryEquals("\"term germ\"~2 flork", null, "\"term germ\"~2 flork");
|
|||
|
AssertQueryEquals("\"term\"~2", null, "term");
|
|||
|
AssertQueryEquals("\" \"~2 germ", null, "germ");
|
|||
|
AssertQueryEquals("\"term germ\"~2^2", null, "\"term germ\"~2^2.0");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestNumber()
|
|||
|
{
|
|||
|
// The numbers go away because SimpleAnalzyer ignores them
|
|||
|
AssertQueryEquals("3", null, "");
|
|||
|
AssertQueryEquals("term 1.0 1 2", null, "term");
|
|||
|
AssertQueryEquals("term term1 term2", null, "term term term");
|
|||
|
|
|||
|
Analyzer a = new StandardAnalyzer(Util.Version.LUCENE_CURRENT);
|
|||
|
AssertQueryEquals("3", a, "3");
|
|||
|
AssertQueryEquals("term 1.0 1 2", a, "term 1.0 1 2");
|
|||
|
AssertQueryEquals("term term1 term2", a, "term term1 term2");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestWildcard()
|
|||
|
{
|
|||
|
AssertQueryEquals("term*", null, "term*");
|
|||
|
AssertQueryEquals("term*^2", null, "term*^2.0");
|
|||
|
AssertQueryEquals("term~", null, "term~0.5");
|
|||
|
AssertQueryEquals("term~0.7", null, "term~0.7");
|
|||
|
AssertQueryEquals("term~^2", null, "term~0.5^2.0");
|
|||
|
AssertQueryEquals("term^2~", null, "term~0.5^2.0");
|
|||
|
AssertQueryEquals("term*germ", null, "term*germ");
|
|||
|
AssertQueryEquals("term*germ^3", null, "term*germ^3.0");
|
|||
|
|
|||
|
Assert.IsTrue(GetQuery("term*", null) is PrefixQuery);
|
|||
|
Assert.IsTrue(GetQuery("term*^2", null) is PrefixQuery);
|
|||
|
Assert.IsTrue(GetQuery("term~", null) is FuzzyQuery);
|
|||
|
Assert.IsTrue(GetQuery("term~0.7", null) is FuzzyQuery);
|
|||
|
FuzzyQuery fq = (FuzzyQuery) GetQuery("term~0.7", null);
|
|||
|
Assert.AreEqual(0.7f, fq.MinSimilarity, 0.1f);
|
|||
|
Assert.AreEqual(FuzzyQuery.defaultPrefixLength, fq.PrefixLength);
|
|||
|
fq = (FuzzyQuery) GetQuery("term~", null);
|
|||
|
Assert.AreEqual(0.5f, fq.MinSimilarity, 0.1f);
|
|||
|
Assert.AreEqual(FuzzyQuery.defaultPrefixLength, fq.PrefixLength);
|
|||
|
|
|||
|
AssertParseException("term~1.1"); // value > 1, throws exception
|
|||
|
|
|||
|
Assert.IsTrue(GetQuery("term*germ", null) is WildcardQuery);
|
|||
|
|
|||
|
/* Tests to see that wild card terms are (or are not) properly
|
|||
|
* lower-cased with propery parser configuration
|
|||
|
*/
|
|||
|
// First prefix queries:
|
|||
|
// by default, convert to lowercase:
|
|||
|
AssertWildcardQueryEquals("Term*", true, "term*");
|
|||
|
// explicitly set lowercase:
|
|||
|
AssertWildcardQueryEquals("term*", true, "term*");
|
|||
|
AssertWildcardQueryEquals("Term*", true, "term*");
|
|||
|
AssertWildcardQueryEquals("TERM*", true, "term*");
|
|||
|
// explicitly disable lowercase conversion:
|
|||
|
AssertWildcardQueryEquals("term*", false, "term*");
|
|||
|
AssertWildcardQueryEquals("Term*", false, "Term*");
|
|||
|
AssertWildcardQueryEquals("TERM*", false, "TERM*");
|
|||
|
// Then 'full' wildcard queries:
|
|||
|
// by default, convert to lowercase:
|
|||
|
AssertWildcardQueryEquals("Te?m", "te?m");
|
|||
|
// explicitly set lowercase:
|
|||
|
AssertWildcardQueryEquals("te?m", true, "te?m");
|
|||
|
AssertWildcardQueryEquals("Te?m", true, "te?m");
|
|||
|
AssertWildcardQueryEquals("TE?M", true, "te?m");
|
|||
|
AssertWildcardQueryEquals("Te?m*gerM", true, "te?m*germ");
|
|||
|
// explicitly disable lowercase conversion:
|
|||
|
AssertWildcardQueryEquals("te?m", false, "te?m");
|
|||
|
AssertWildcardQueryEquals("Te?m", false, "Te?m");
|
|||
|
AssertWildcardQueryEquals("TE?M", false, "TE?M");
|
|||
|
AssertWildcardQueryEquals("Te?m*gerM", false, "Te?m*gerM");
|
|||
|
// Fuzzy queries:
|
|||
|
AssertWildcardQueryEquals("Term~", "term~0.5");
|
|||
|
AssertWildcardQueryEquals("Term~", true, "term~0.5");
|
|||
|
AssertWildcardQueryEquals("Term~", false, "Term~0.5");
|
|||
|
// Range queries:
|
|||
|
AssertWildcardQueryEquals("[A TO C]", "[a TO c]");
|
|||
|
AssertWildcardQueryEquals("[A TO C]", true, "[a TO c]");
|
|||
|
AssertWildcardQueryEquals("[A TO C]", false, "[A TO C]");
|
|||
|
|
|||
|
// Test suffix queries: first disallow
|
|||
|
Assert.Throws<ParseException>(() => AssertWildcardQueryEquals("*Term", true, "*term"));
|
|||
|
Assert.Throws<ParseException>(() => AssertWildcardQueryEquals("?Term", true, "?term"));
|
|||
|
|
|||
|
// Test suffix queries: then allow
|
|||
|
AssertWildcardQueryEquals("*Term", true, "*term", true);
|
|||
|
AssertWildcardQueryEquals("?Term", true, "?term", true);
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestLeadingWildcardType()
|
|||
|
{
|
|||
|
QueryParser qp = GetParser(null);
|
|||
|
qp.AllowLeadingWildcard = true;
|
|||
|
Assert.AreEqual(typeof(WildcardQuery), qp.Parse("t*erm*").GetType());
|
|||
|
Assert.AreEqual(typeof(WildcardQuery), qp.Parse("?term*").GetType());
|
|||
|
Assert.AreEqual(typeof(WildcardQuery), qp.Parse("*term*").GetType());
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestQPA()
|
|||
|
{
|
|||
|
AssertQueryEquals("term term^3.0 term", qpAnalyzer, "term term^3.0 term");
|
|||
|
AssertQueryEquals("term stop^3.0 term", qpAnalyzer, "term term");
|
|||
|
|
|||
|
AssertQueryEquals("term term term", qpAnalyzer, "term term term");
|
|||
|
AssertQueryEquals("term +stop term", qpAnalyzer, "term term");
|
|||
|
AssertQueryEquals("term -stop term", qpAnalyzer, "term term");
|
|||
|
|
|||
|
AssertQueryEquals("drop AND (stop) AND roll", qpAnalyzer, "+drop +roll");
|
|||
|
AssertQueryEquals("term +(stop) term", qpAnalyzer, "term term");
|
|||
|
AssertQueryEquals("term -(stop) term", qpAnalyzer, "term term");
|
|||
|
|
|||
|
AssertQueryEquals("drop AND stop AND roll", qpAnalyzer, "+drop +roll");
|
|||
|
AssertQueryEquals("term phrase term", qpAnalyzer, "term \"phrase1 phrase2\" term");
|
|||
|
AssertQueryEquals("term AND NOT phrase term", qpAnalyzer, "+term -\"phrase1 phrase2\" term");
|
|||
|
AssertQueryEquals("stop^3", qpAnalyzer, "");
|
|||
|
AssertQueryEquals("stop", qpAnalyzer, "");
|
|||
|
AssertQueryEquals("(stop)^3", qpAnalyzer, "");
|
|||
|
AssertQueryEquals("((stop))^3", qpAnalyzer, "");
|
|||
|
AssertQueryEquals("(stop^3)", qpAnalyzer, "");
|
|||
|
AssertQueryEquals("((stop)^3)", qpAnalyzer, "");
|
|||
|
AssertQueryEquals("(stop)", qpAnalyzer, "");
|
|||
|
AssertQueryEquals("((stop))", qpAnalyzer, "");
|
|||
|
Assert.IsTrue(GetQuery("term term term", qpAnalyzer) is BooleanQuery);
|
|||
|
Assert.IsTrue(GetQuery("term +stop", qpAnalyzer) is TermQuery);
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestRange()
|
|||
|
{
|
|||
|
AssertQueryEquals("[ a TO z]", null, "[a TO z]");
|
|||
|
Assert.AreEqual(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT, ((TermRangeQuery)GetQuery("[ a TO z]", null)).RewriteMethod);
|
|||
|
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new SimpleAnalyzer());
|
|||
|
qp.MultiTermRewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
|
|||
|
Assert.AreEqual(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE, ((TermRangeQuery)qp.Parse("[ a TO z]")).RewriteMethod);
|
|||
|
|
|||
|
AssertQueryEquals("[ a TO z ]", null, "[a TO z]");
|
|||
|
AssertQueryEquals("{ a TO z}", null, "{a TO z}");
|
|||
|
AssertQueryEquals("{ a TO z }", null, "{a TO z}");
|
|||
|
AssertQueryEquals("{ a TO z }^2.0", null, "{a TO z}^2.0");
|
|||
|
AssertQueryEquals("[ a TO z] OR bar", null, "[a TO z] bar");
|
|||
|
AssertQueryEquals("[ a TO z] AND bar", null, "+[a TO z] +bar");
|
|||
|
AssertQueryEquals("( bar blar { a TO z}) ", null, "bar blar {a TO z}");
|
|||
|
AssertQueryEquals("gack ( bar blar { a TO z}) ", null, "gack (bar blar {a TO z})");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestFarsiRangeCollating()
|
|||
|
{
|
|||
|
|
|||
|
RAMDirectory ramDir = new RAMDirectory();
|
|||
|
IndexWriter iw = new IndexWriter(ramDir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|||
|
Document doc = new Document();
|
|||
|
doc.Add(new Field("content", "\u0633\u0627\u0628", Field.Store.YES, Field.Index.NOT_ANALYZED));
|
|||
|
iw.AddDocument(doc);
|
|||
|
iw.Close();
|
|||
|
IndexSearcher is_Renamed = new IndexSearcher(ramDir, true);
|
|||
|
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "content", new WhitespaceAnalyzer());
|
|||
|
|
|||
|
// Neither Java 1.4.2 nor 1.5.0 has Farsi Locale collation available in
|
|||
|
// RuleBasedCollator. However, the Arabic Locale seems to order the Farsi
|
|||
|
// characters properly.
|
|||
|
System.Globalization.CompareInfo c = new System.Globalization.CultureInfo("ar").CompareInfo;
|
|||
|
qp.RangeCollator = c;
|
|||
|
|
|||
|
// Unicode order would include U+0633 in [ U+062F - U+0698 ], but Farsi
|
|||
|
// orders the U+0698 character before the U+0633 character, so the single
|
|||
|
// index Term below should NOT be returned by a ConstantScoreRangeQuery
|
|||
|
// with a Farsi Collator (or an Arabic one for the case when Farsi is not
|
|||
|
// supported).
|
|||
|
|
|||
|
// Test ConstantScoreRangeQuery
|
|||
|
qp.MultiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE;
|
|||
|
ScoreDoc[] result = is_Renamed.Search(qp.Parse("[ \u062F TO \u0698 ]"), null, 1000).ScoreDocs;
|
|||
|
Assert.AreEqual(0, result.Length, "The index Term should not be included.");
|
|||
|
|
|||
|
result = is_Renamed.Search(qp.Parse("[ \u0633 TO \u0638 ]"), null, 1000).ScoreDocs;
|
|||
|
Assert.AreEqual(1, result.Length, "The index Term should be included.");
|
|||
|
|
|||
|
// Test TermRangeQuery
|
|||
|
qp.MultiTermRewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
|
|||
|
result = is_Renamed.Search(qp.Parse("[ \u062F TO \u0698 ]"), null, 1000).ScoreDocs;
|
|||
|
Assert.AreEqual(0, result.Length, "The index Term should not be included.");
|
|||
|
|
|||
|
result = is_Renamed.Search(qp.Parse("[ \u0633 TO \u0638 ]"), null, 1000).ScoreDocs;
|
|||
|
Assert.AreEqual(1, result.Length, "The index Term should be included.");
|
|||
|
|
|||
|
is_Renamed.Close();
|
|||
|
}
|
|||
|
|
|||
|
private System.String EscapeDateString(System.String s)
|
|||
|
{
|
|||
|
if (s.IndexOf(" ") > - 1)
|
|||
|
{
|
|||
|
return "\"" + s + "\"";
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return s;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>for testing legacy DateField support </summary>
|
|||
|
private System.String GetLegacyDate(System.String s)
|
|||
|
{
|
|||
|
System.DateTime tempAux = System.DateTime.Parse(s, System.Globalization.CultureInfo.CurrentCulture);
|
|||
|
return DateField.DateToString(tempAux);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>for testing DateTools support </summary>
|
|||
|
private System.String GetDate(System.String s, DateTools.Resolution resolution)
|
|||
|
{
|
|||
|
System.DateTime tempAux = System.DateTime.Parse(s, System.Globalization.CultureInfo.CurrentCulture);
|
|||
|
return GetDate(tempAux, resolution);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>for testing DateTools support </summary>
|
|||
|
private System.String GetDate(System.DateTime d, DateTools.Resolution resolution)
|
|||
|
{
|
|||
|
if (resolution == null)
|
|||
|
{
|
|||
|
return DateField.DateToString(d);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return DateTools.DateToString(d, resolution);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private System.String GetLocalizedDate(int year, int month, int day, bool extendLastDate)
|
|||
|
{
|
|||
|
System.Globalization.Calendar calendar = new System.Globalization.GregorianCalendar();
|
|||
|
System.DateTime temp = new System.DateTime(year, month, day, calendar);
|
|||
|
if (extendLastDate)
|
|||
|
{
|
|||
|
temp = temp.AddHours(23);
|
|||
|
temp = temp.AddMinutes(59);
|
|||
|
temp = temp.AddSeconds(59);
|
|||
|
temp = temp.AddMilliseconds(999);
|
|||
|
}
|
|||
|
return temp.ToShortDateString();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>for testing legacy DateField support </summary>
|
|||
|
[Test]
|
|||
|
public virtual void TestLegacyDateRange()
|
|||
|
{
|
|||
|
System.String startDate = GetLocalizedDate(2002, 1, 1, false);
|
|||
|
System.String endDate = GetLocalizedDate(2002, 1, 4, false);
|
|||
|
System.Globalization.Calendar endDateExpected = new System.Globalization.GregorianCalendar();
|
|||
|
System.DateTime tempAux = new System.DateTime(2002, 1, 4, 23, 59, 59, 999, endDateExpected);
|
|||
|
AssertQueryEquals("[ " + EscapeDateString(startDate) + " TO " + EscapeDateString(endDate) + "]", null, "[" + GetLegacyDate(startDate) + " TO " + DateField.DateToString(tempAux) + "]");
|
|||
|
AssertQueryEquals("{ " + EscapeDateString(startDate) + " " + EscapeDateString(endDate) + " }", null, "{" + GetLegacyDate(startDate) + " TO " + GetLegacyDate(endDate) + "}");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestDateRange()
|
|||
|
{
|
|||
|
System.String startDate = GetLocalizedDate(2002, 1, 1, false);
|
|||
|
System.String endDate = GetLocalizedDate(2002, 1, 4, false);
|
|||
|
System.Globalization.Calendar calendar = new System.Globalization.GregorianCalendar();
|
|||
|
System.DateTime endDateExpected = new System.DateTime(2002, 1, 4, 23, 59, 59, 999, calendar);
|
|||
|
System.String defaultField = "default";
|
|||
|
System.String monthField = "month";
|
|||
|
System.String hourField = "hour";
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new SimpleAnalyzer());
|
|||
|
|
|||
|
// Don't set any date resolution and verify if DateField is used
|
|||
|
System.DateTime tempAux = endDateExpected;
|
|||
|
AssertDateRangeQueryEquals(qp, defaultField, startDate, endDate, tempAux, null);
|
|||
|
|
|||
|
// set a field specific date resolution
|
|||
|
qp.SetDateResolution(monthField, DateTools.Resolution.MONTH);
|
|||
|
|
|||
|
// DateField should still be used for defaultField
|
|||
|
System.DateTime tempAux2 = endDateExpected;
|
|||
|
AssertDateRangeQueryEquals(qp, defaultField, startDate, endDate, tempAux2, null);
|
|||
|
|
|||
|
// set default date resolution to MILLISECOND
|
|||
|
qp.SetDateResolution(DateTools.Resolution.MILLISECOND);
|
|||
|
|
|||
|
// set second field specific date resolution
|
|||
|
qp.SetDateResolution(hourField, DateTools.Resolution.HOUR);
|
|||
|
|
|||
|
// for this field no field specific date resolution has been set,
|
|||
|
// so verify if the default resolution is used
|
|||
|
System.DateTime tempAux3 = endDateExpected;
|
|||
|
AssertDateRangeQueryEquals(qp, defaultField, startDate, endDate, tempAux3, DateTools.Resolution.MILLISECOND);
|
|||
|
|
|||
|
// verify if field specific date resolutions are used for these two fields
|
|||
|
System.DateTime tempAux4 = endDateExpected;
|
|||
|
AssertDateRangeQueryEquals(qp, monthField, startDate, endDate, tempAux4, DateTools.Resolution.MONTH);
|
|||
|
|
|||
|
System.DateTime tempAux5 = endDateExpected;
|
|||
|
AssertDateRangeQueryEquals(qp, hourField, startDate, endDate, tempAux5, DateTools.Resolution.HOUR);
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertDateRangeQueryEquals(QueryParser qp, System.String field, System.String startDate, System.String endDate, System.DateTime endDateInclusive, DateTools.Resolution resolution)
|
|||
|
{
|
|||
|
AssertQueryEquals(qp, field, field + ":[" + EscapeDateString(startDate) + " TO " + EscapeDateString(endDate) + "]", "[" + GetDate(startDate, resolution) + " TO " + GetDate(endDateInclusive, resolution) + "]");
|
|||
|
AssertQueryEquals(qp, field, field + ":{" + EscapeDateString(startDate) + " TO " + EscapeDateString(endDate) + "}", "{" + GetDate(startDate, resolution) + " TO " + GetDate(endDate, resolution) + "}");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestEscaped()
|
|||
|
{
|
|||
|
Analyzer a = new WhitespaceAnalyzer();
|
|||
|
|
|||
|
/*assertQueryEquals("\\[brackets", a, "\\[brackets");
|
|||
|
assertQueryEquals("\\[brackets", null, "brackets");
|
|||
|
assertQueryEquals("\\\\", a, "\\\\");
|
|||
|
assertQueryEquals("\\+blah", a, "\\+blah");
|
|||
|
assertQueryEquals("\\(blah", a, "\\(blah");
|
|||
|
|
|||
|
assertQueryEquals("\\-blah", a, "\\-blah");
|
|||
|
assertQueryEquals("\\!blah", a, "\\!blah");
|
|||
|
assertQueryEquals("\\{blah", a, "\\{blah");
|
|||
|
assertQueryEquals("\\}blah", a, "\\}blah");
|
|||
|
assertQueryEquals("\\:blah", a, "\\:blah");
|
|||
|
assertQueryEquals("\\^blah", a, "\\^blah");
|
|||
|
assertQueryEquals("\\[blah", a, "\\[blah");
|
|||
|
assertQueryEquals("\\]blah", a, "\\]blah");
|
|||
|
assertQueryEquals("\\\"blah", a, "\\\"blah");
|
|||
|
assertQueryEquals("\\(blah", a, "\\(blah");
|
|||
|
assertQueryEquals("\\)blah", a, "\\)blah");
|
|||
|
assertQueryEquals("\\~blah", a, "\\~blah");
|
|||
|
assertQueryEquals("\\*blah", a, "\\*blah");
|
|||
|
assertQueryEquals("\\?blah", a, "\\?blah");
|
|||
|
//assertQueryEquals("foo \\&\\& bar", a, "foo \\&\\& bar");
|
|||
|
//assertQueryEquals("foo \\|| bar", a, "foo \\|| bar");
|
|||
|
//assertQueryEquals("foo \\AND bar", a, "foo \\AND bar");*/
|
|||
|
|
|||
|
AssertQueryEquals("\\a", a, "a");
|
|||
|
|
|||
|
AssertQueryEquals("a\\-b:c", a, "a-b:c");
|
|||
|
AssertQueryEquals("a\\+b:c", a, "a+b:c");
|
|||
|
AssertQueryEquals("a\\:b:c", a, "a:b:c");
|
|||
|
AssertQueryEquals("a\\\\b:c", a, "a\\b:c");
|
|||
|
|
|||
|
AssertQueryEquals("a:b\\-c", a, "a:b-c");
|
|||
|
AssertQueryEquals("a:b\\+c", a, "a:b+c");
|
|||
|
AssertQueryEquals("a:b\\:c", a, "a:b:c");
|
|||
|
AssertQueryEquals("a:b\\\\c", a, "a:b\\c");
|
|||
|
|
|||
|
AssertQueryEquals("a:b\\-c*", a, "a:b-c*");
|
|||
|
AssertQueryEquals("a:b\\+c*", a, "a:b+c*");
|
|||
|
AssertQueryEquals("a:b\\:c*", a, "a:b:c*");
|
|||
|
|
|||
|
AssertQueryEquals("a:b\\\\c*", a, "a:b\\c*");
|
|||
|
|
|||
|
AssertQueryEquals("a:b\\-?c", a, "a:b-?c");
|
|||
|
AssertQueryEquals("a:b\\+?c", a, "a:b+?c");
|
|||
|
AssertQueryEquals("a:b\\:?c", a, "a:b:?c");
|
|||
|
|
|||
|
AssertQueryEquals("a:b\\\\?c", a, "a:b\\?c");
|
|||
|
|
|||
|
AssertQueryEquals("a:b\\-c~", a, "a:b-c~0.5");
|
|||
|
AssertQueryEquals("a:b\\+c~", a, "a:b+c~0.5");
|
|||
|
AssertQueryEquals("a:b\\:c~", a, "a:b:c~0.5");
|
|||
|
AssertQueryEquals("a:b\\\\c~", a, "a:b\\c~0.5");
|
|||
|
|
|||
|
AssertQueryEquals("[ a\\- TO a\\+ ]", null, "[a- TO a+]");
|
|||
|
AssertQueryEquals("[ a\\: TO a\\~ ]", null, "[a: TO a~]");
|
|||
|
AssertQueryEquals("[ a\\\\ TO a\\* ]", null, "[a\\ TO a*]");
|
|||
|
|
|||
|
AssertQueryEquals("[\"c\\:\\\\temp\\\\\\~foo0.txt\" TO \"c\\:\\\\temp\\\\\\~foo9.txt\"]", a, "[c:\\temp\\~foo0.txt TO c:\\temp\\~foo9.txt]");
|
|||
|
|
|||
|
AssertQueryEquals("a\\\\\\+b", a, "a\\+b");
|
|||
|
|
|||
|
AssertQueryEquals("a \\\"b c\\\" d", a, "a \"b c\" d");
|
|||
|
AssertQueryEquals("\"a \\\"b c\\\" d\"", a, "\"a \"b c\" d\"");
|
|||
|
AssertQueryEquals("\"a \\+b c d\"", a, "\"a +b c d\"");
|
|||
|
|
|||
|
AssertQueryEquals("c\\:\\\\temp\\\\\\~foo.txt", a, "c:\\temp\\~foo.txt");
|
|||
|
|
|||
|
AssertParseException("XY\\"); // there must be a character after the escape char
|
|||
|
|
|||
|
// test unicode escaping
|
|||
|
AssertQueryEquals("a\\u0062c", a, "abc");
|
|||
|
AssertQueryEquals("XY\\u005a", a, "XYZ");
|
|||
|
AssertQueryEquals("XY\\u005A", a, "XYZ");
|
|||
|
AssertQueryEquals("\"a \\\\\\u0028\\u0062\\\" c\"", a, "\"a \\(b\" c\"");
|
|||
|
|
|||
|
AssertParseException("XY\\u005G"); // test non-hex character in escaped unicode sequence
|
|||
|
AssertParseException("XY\\u005"); // test incomplete escaped unicode sequence
|
|||
|
|
|||
|
// Tests bug LUCENE-800
|
|||
|
AssertQueryEquals("(item:\\\\ item:ABCD\\\\)", a, "item:\\ item:ABCD\\");
|
|||
|
AssertParseException("(item:\\\\ item:ABCD\\\\))"); // unmatched closing paranthesis
|
|||
|
AssertQueryEquals("\\*", a, "*");
|
|||
|
AssertQueryEquals("\\\\", a, "\\"); // escaped backslash
|
|||
|
|
|||
|
AssertParseException("\\"); // a backslash must always be escaped
|
|||
|
|
|||
|
// LUCENE-1189
|
|||
|
AssertQueryEquals("(\"a\\\\\") or (\"b\")", a, "a\\ or b");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestQueryStringEscaping()
|
|||
|
{
|
|||
|
Analyzer a = new WhitespaceAnalyzer();
|
|||
|
|
|||
|
AssertEscapedQueryEquals("a-b:c", a, "a\\-b\\:c");
|
|||
|
AssertEscapedQueryEquals("a+b:c", a, "a\\+b\\:c");
|
|||
|
AssertEscapedQueryEquals("a:b:c", a, "a\\:b\\:c");
|
|||
|
AssertEscapedQueryEquals("a\\b:c", a, "a\\\\b\\:c");
|
|||
|
|
|||
|
AssertEscapedQueryEquals("a:b-c", a, "a\\:b\\-c");
|
|||
|
AssertEscapedQueryEquals("a:b+c", a, "a\\:b\\+c");
|
|||
|
AssertEscapedQueryEquals("a:b:c", a, "a\\:b\\:c");
|
|||
|
AssertEscapedQueryEquals("a:b\\c", a, "a\\:b\\\\c");
|
|||
|
|
|||
|
AssertEscapedQueryEquals("a:b-c*", a, "a\\:b\\-c\\*");
|
|||
|
AssertEscapedQueryEquals("a:b+c*", a, "a\\:b\\+c\\*");
|
|||
|
AssertEscapedQueryEquals("a:b:c*", a, "a\\:b\\:c\\*");
|
|||
|
|
|||
|
AssertEscapedQueryEquals("a:b\\\\c*", a, "a\\:b\\\\\\\\c\\*");
|
|||
|
|
|||
|
AssertEscapedQueryEquals("a:b-?c", a, "a\\:b\\-\\?c");
|
|||
|
AssertEscapedQueryEquals("a:b+?c", a, "a\\:b\\+\\?c");
|
|||
|
AssertEscapedQueryEquals("a:b:?c", a, "a\\:b\\:\\?c");
|
|||
|
|
|||
|
AssertEscapedQueryEquals("a:b?c", a, "a\\:b\\?c");
|
|||
|
|
|||
|
AssertEscapedQueryEquals("a:b-c~", a, "a\\:b\\-c\\~");
|
|||
|
AssertEscapedQueryEquals("a:b+c~", a, "a\\:b\\+c\\~");
|
|||
|
AssertEscapedQueryEquals("a:b:c~", a, "a\\:b\\:c\\~");
|
|||
|
AssertEscapedQueryEquals("a:b\\c~", a, "a\\:b\\\\c\\~");
|
|||
|
|
|||
|
AssertEscapedQueryEquals("[ a - TO a+ ]", null, "\\[ a \\- TO a\\+ \\]");
|
|||
|
AssertEscapedQueryEquals("[ a : TO a~ ]", null, "\\[ a \\: TO a\\~ \\]");
|
|||
|
AssertEscapedQueryEquals("[ a\\ TO a* ]", null, "\\[ a\\\\ TO a\\* \\]");
|
|||
|
|
|||
|
// LUCENE-881
|
|||
|
AssertEscapedQueryEquals("|| abc ||", a, "\\|\\| abc \\|\\|");
|
|||
|
AssertEscapedQueryEquals("&& abc &&", a, "\\&\\& abc \\&\\&");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestTabNewlineCarriageReturn()
|
|||
|
{
|
|||
|
AssertQueryEqualsDOA("+weltbank +worlbank", null, "+weltbank +worlbank");
|
|||
|
|
|||
|
AssertQueryEqualsDOA("+weltbank\n+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \n+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \n +worlbank", null, "+weltbank +worlbank");
|
|||
|
|
|||
|
AssertQueryEqualsDOA("+weltbank\r+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \r+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \r +worlbank", null, "+weltbank +worlbank");
|
|||
|
|
|||
|
AssertQueryEqualsDOA("+weltbank\r\n+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \r\n+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \r\n +worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \r \n +worlbank", null, "+weltbank +worlbank");
|
|||
|
|
|||
|
AssertQueryEqualsDOA("+weltbank\t+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \t+worlbank", null, "+weltbank +worlbank");
|
|||
|
AssertQueryEqualsDOA("weltbank \t +worlbank", null, "+weltbank +worlbank");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestSimpleDAO()
|
|||
|
{
|
|||
|
AssertQueryEqualsDOA("term term term", null, "+term +term +term");
|
|||
|
AssertQueryEqualsDOA("term +term term", null, "+term +term +term");
|
|||
|
AssertQueryEqualsDOA("term term +term", null, "+term +term +term");
|
|||
|
AssertQueryEqualsDOA("term +term +term", null, "+term +term +term");
|
|||
|
AssertQueryEqualsDOA("-term term term", null, "-term +term +term");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestBoost()
|
|||
|
{
|
|||
|
var stopWords = Support.Compatibility.SetFactory.CreateHashSet<string>();
|
|||
|
stopWords.Add("on");
|
|||
|
StandardAnalyzer oneStopAnalyzer = new StandardAnalyzer(Version.LUCENE_CURRENT, stopWords);
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", oneStopAnalyzer);
|
|||
|
Query q = qp.Parse("on^1.0");
|
|||
|
Assert.IsNotNull(q);
|
|||
|
q = qp.Parse("\"hello\"^2.0");
|
|||
|
Assert.IsNotNull(q);
|
|||
|
Assert.AreEqual(q.Boost, (float) 2.0, (float) 0.5);
|
|||
|
q = qp.Parse("hello^2.0");
|
|||
|
Assert.IsNotNull(q);
|
|||
|
Assert.AreEqual(q.Boost, (float) 2.0, (float) 0.5);
|
|||
|
q = qp.Parse("\"on\"^1.0");
|
|||
|
Assert.IsNotNull(q);
|
|||
|
|
|||
|
QueryParser qp2 = new QueryParser(Version.LUCENE_CURRENT, "field", new StandardAnalyzer(Util.Version.LUCENE_CURRENT));
|
|||
|
q = qp2.Parse("the^3");
|
|||
|
// "the" is a stop word so the result is an empty query:
|
|||
|
Assert.IsNotNull(q);
|
|||
|
Assert.AreEqual("", q.ToString());
|
|||
|
Assert.AreEqual(1.0f, q.Boost, 0.01f);
|
|||
|
}
|
|||
|
|
|||
|
public virtual void AssertParseException(System.String queryString)
|
|||
|
{
|
|||
|
Assert.Throws<ParseException>(() => GetQuery(queryString, null), "ParseException expected, not thrown");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestException()
|
|||
|
{
|
|||
|
AssertParseException("\"some phrase");
|
|||
|
AssertParseException("(foo bar");
|
|||
|
AssertParseException("foo bar))");
|
|||
|
AssertParseException("field:term:with:colon some more terms");
|
|||
|
AssertParseException("(sub query)^5.0^2.0 plus more");
|
|||
|
AssertParseException("secret AND illegal) AND access:confidential");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestCustomQueryParserWildcard()
|
|||
|
{
|
|||
|
Assert.Throws<ParseException>(() => new QPTestParser("contents", new WhitespaceAnalyzer()).Parse("a?t"),
|
|||
|
"Wildcard queries should not be allowed");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestCustomQueryParserFuzzy()
|
|||
|
{
|
|||
|
Assert.Throws<ParseException>(() => new QPTestParser("contents", new WhitespaceAnalyzer()).Parse("xunit~"),
|
|||
|
"Fuzzy queries should not be allowed");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestBooleanQuery()
|
|||
|
{
|
|||
|
BooleanQuery.MaxClauseCount = 2;
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new WhitespaceAnalyzer());
|
|||
|
Assert.Throws<ParseException>(() => qp.Parse("one two three"),
|
|||
|
"ParseException expected due to too many boolean clauses");
|
|||
|
}
|
|||
|
|
|||
|
/// <summary> This test differs from TestPrecedenceQueryParser</summary>
|
|||
|
[Test]
|
|||
|
public virtual void TestPrecedence()
|
|||
|
{
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new WhitespaceAnalyzer());
|
|||
|
Query query1 = qp.Parse("A AND B OR C AND D");
|
|||
|
Query query2 = qp.Parse("+A +B +C +D");
|
|||
|
Assert.AreEqual(query1, query2);
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestLocalDateFormat()
|
|||
|
{
|
|||
|
RAMDirectory ramDir = new RAMDirectory();
|
|||
|
IndexWriter iw = new IndexWriter(ramDir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|||
|
AddDateDoc("a", 2005, 12, 2, 10, 15, 33, iw);
|
|||
|
AddDateDoc("b", 2005, 12, 4, 22, 15, 0, iw);
|
|||
|
iw.Close();
|
|||
|
IndexSearcher is_Renamed = new IndexSearcher(ramDir, true);
|
|||
|
AssertHits(1, "[12/1/2005 TO 12/3/2005]", is_Renamed);
|
|||
|
AssertHits(2, "[12/1/2005 TO 12/4/2005]", is_Renamed);
|
|||
|
AssertHits(1, "[12/3/2005 TO 12/4/2005]", is_Renamed);
|
|||
|
AssertHits(1, "{12/1/2005 TO 12/3/2005}", is_Renamed);
|
|||
|
AssertHits(1, "{12/1/2005 TO 12/4/2005}", is_Renamed);
|
|||
|
AssertHits(0, "{12/3/2005 TO 12/4/2005}", is_Renamed);
|
|||
|
is_Renamed.Close();
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestStarParsing()
|
|||
|
{
|
|||
|
int[] type = new int[1];
|
|||
|
QueryParser qp = new AnonymousClassQueryParser(type, this, "field", new WhitespaceAnalyzer());
|
|||
|
|
|||
|
TermQuery tq;
|
|||
|
|
|||
|
tq = (TermQuery) qp.Parse("foo:zoo*");
|
|||
|
Assert.AreEqual("zoo", tq.Term.Text);
|
|||
|
Assert.AreEqual(2, type[0]);
|
|||
|
|
|||
|
tq = (TermQuery) qp.Parse("foo:zoo*^2");
|
|||
|
Assert.AreEqual("zoo", tq.Term.Text);
|
|||
|
Assert.AreEqual(2, type[0]);
|
|||
|
Assert.AreEqual(tq.Boost, 2, 0);
|
|||
|
|
|||
|
tq = (TermQuery) qp.Parse("foo:*");
|
|||
|
Assert.AreEqual("*", tq.Term.Text);
|
|||
|
Assert.AreEqual(1, type[0]); // could be a valid prefix query in the future too
|
|||
|
|
|||
|
tq = (TermQuery) qp.Parse("foo:*^2");
|
|||
|
Assert.AreEqual("*", tq.Term.Text);
|
|||
|
Assert.AreEqual(1, type[0]);
|
|||
|
Assert.AreEqual(tq.Boost, 2, 0);
|
|||
|
|
|||
|
tq = (TermQuery) qp.Parse("*:foo");
|
|||
|
Assert.AreEqual("*", tq.Term.Field);
|
|||
|
Assert.AreEqual("foo", tq.Term.Text);
|
|||
|
Assert.AreEqual(3, type[0]);
|
|||
|
|
|||
|
tq = (TermQuery) qp.Parse("*:*");
|
|||
|
Assert.AreEqual("*", tq.Term.Field);
|
|||
|
Assert.AreEqual("*", tq.Term.Text);
|
|||
|
Assert.AreEqual(1, type[0]); // could be handled as a prefix query in the future
|
|||
|
|
|||
|
tq = (TermQuery) qp.Parse("(*:*)");
|
|||
|
Assert.AreEqual("*", tq.Term.Field);
|
|||
|
Assert.AreEqual("*", tq.Term.Text);
|
|||
|
Assert.AreEqual(1, type[0]);
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestStopwords()
|
|||
|
{
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "a",
|
|||
|
new StopAnalyzer(Version.LUCENE_CURRENT,
|
|||
|
StopFilter.MakeStopSet(new[] {"the", "foo"})));
|
|||
|
Query result = qp.Parse("a:the OR a:foo");
|
|||
|
Assert.IsNotNull(result, "result is null and it shouldn't be");
|
|||
|
Assert.IsTrue(result is BooleanQuery, "result is not a BooleanQuery");
|
|||
|
Assert.IsTrue(((BooleanQuery) result).Clauses.Count == 0, ((BooleanQuery) result).Clauses.Count + " does not equal: " + 0);
|
|||
|
result = qp.Parse("a:woo OR a:the");
|
|||
|
Assert.IsNotNull(result, "result is null and it shouldn't be");
|
|||
|
Assert.IsTrue(result is TermQuery, "result is not a TermQuery");
|
|||
|
result = qp.Parse("(fieldX:xxxxx OR fieldy:xxxxxxxx)^2 AND (fieldx:the OR fieldy:foo)");
|
|||
|
Assert.IsNotNull(result, "result is null and it shouldn't be");
|
|||
|
Assert.IsTrue(result is BooleanQuery, "result is not a BooleanQuery");
|
|||
|
System.Console.Out.WriteLine("Result: " + result);
|
|||
|
Assert.IsTrue(((BooleanQuery) result).Clauses.Count == 2, ((BooleanQuery) result).Clauses.Count + " does not equal: " + 2);
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestPositionIncrement()
|
|||
|
{
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "a",
|
|||
|
new StopAnalyzer(Version.LUCENE_CURRENT,
|
|||
|
StopFilter.MakeStopSet(new[] {"the", "in", "are", "this"})));
|
|||
|
qp.EnablePositionIncrements = true;
|
|||
|
string qtxt = "\"the words in poisitions pos02578 are stopped in this phrasequery\"";
|
|||
|
// 0 2 5 7 8
|
|||
|
int[] expectedPositions = new int[] {1, 3, 4, 6, 9};
|
|||
|
PhraseQuery pq = (PhraseQuery) qp.Parse(qtxt);
|
|||
|
//System.out.println("Query text: "+qtxt);
|
|||
|
//System.out.println("Result: "+pq);
|
|||
|
Term[] t = pq.GetTerms();
|
|||
|
int[] pos = pq.GetPositions();
|
|||
|
for (int i = 0; i < t.Length; i++)
|
|||
|
{
|
|||
|
//System.out.println(i+". "+t[i]+" pos: "+pos[i]);
|
|||
|
Assert.AreEqual(expectedPositions[i], pos[i], "term " + i + " = " + t[i] + " has wrong term-position!");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public virtual void TestMatchAllDocs()
|
|||
|
{
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new WhitespaceAnalyzer());
|
|||
|
Assert.AreEqual(new MatchAllDocsQuery(), qp.Parse("*:*"));
|
|||
|
Assert.AreEqual(new MatchAllDocsQuery(), qp.Parse("(*:*)"));
|
|||
|
BooleanQuery bq = (BooleanQuery) qp.Parse("+*:* -*:*");
|
|||
|
Assert.IsTrue(bq.GetClauses()[0].Query is MatchAllDocsQuery);
|
|||
|
Assert.IsTrue(bq.GetClauses()[1].Query is MatchAllDocsQuery);
|
|||
|
}
|
|||
|
|
|||
|
private void AssertHits(int expected, System.String query, IndexSearcher is_Renamed)
|
|||
|
{
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "date", new WhitespaceAnalyzer());
|
|||
|
qp.Locale = new System.Globalization.CultureInfo("en-US");
|
|||
|
Query q = qp.Parse(query);
|
|||
|
ScoreDoc[] hits = is_Renamed.Search(q, null, 1000).ScoreDocs;
|
|||
|
Assert.AreEqual(expected, hits.Length);
|
|||
|
}
|
|||
|
|
|||
|
private static void AddDateDoc(System.String content, int year, int month, int day, int hour, int minute, int second, IndexWriter iw)
|
|||
|
{
|
|||
|
Document d = new Document();
|
|||
|
d.Add(new Field("f", content, Field.Store.YES, Field.Index.ANALYZED));
|
|||
|
System.Globalization.Calendar cal = new System.Globalization.GregorianCalendar();
|
|||
|
System.DateTime tempAux = new System.DateTime(year, month, day, hour, minute, second, cal);
|
|||
|
d.Add(new Field("date", DateField.DateToString(tempAux), Field.Store.YES, Field.Index.NOT_ANALYZED));
|
|||
|
iw.AddDocument(d);
|
|||
|
}
|
|||
|
|
|||
|
[TearDown]
|
|||
|
public override void TearDown()
|
|||
|
{
|
|||
|
base.TearDown();
|
|||
|
BooleanQuery.MaxClauseCount = originalMaxClauses;
|
|||
|
}
|
|||
|
|
|||
|
// LUCENE-2002: make sure defaults for StandardAnalyzer's
|
|||
|
// enableStopPositionIncr & QueryParser's enablePosIncr
|
|||
|
// "match"
|
|||
|
[Test]
|
|||
|
public virtual void TestPositionIncrements()
|
|||
|
{
|
|||
|
Directory dir = new MockRAMDirectory();
|
|||
|
Analyzer a = new StandardAnalyzer(Version.LUCENE_CURRENT);
|
|||
|
IndexWriter w = new IndexWriter(dir, a, IndexWriter.MaxFieldLength.UNLIMITED);
|
|||
|
Document doc = new Document();
|
|||
|
doc.Add(new Field("f", "the wizard of ozzy", Field.Store.NO, Field.Index.ANALYZED));
|
|||
|
w.AddDocument(doc);
|
|||
|
IndexReader r = w.GetReader();
|
|||
|
w.Close();
|
|||
|
IndexSearcher s = new IndexSearcher(r);
|
|||
|
QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "f", a);
|
|||
|
Query q = qp.Parse("\"wizard of ozzy\"");
|
|||
|
Assert.AreEqual(1, s.Search(q, 1).TotalHits);
|
|||
|
r.Close();
|
|||
|
dir.Close();
|
|||
|
}
|
|||
|
|
|||
|
// LUCENE-2002: when we run javacc to regen QueryParser,
|
|||
|
// we also run a replaceregexp step to fix 2 of the public
|
|||
|
// ctors (change them to protected):
|
|||
|
//
|
|||
|
// protected QueryParser(CharStream stream)
|
|||
|
//
|
|||
|
// protected QueryParser(QueryParserTokenManager tm)
|
|||
|
//
|
|||
|
// This test is here as a safety, in case that ant step
|
|||
|
// doesn't work for some reason.
|
|||
|
[Test]
|
|||
|
public virtual void TestProtectedCtors()
|
|||
|
{
|
|||
|
// If the return type is not null, then fail the assertion.
|
|||
|
Assert.IsNull(typeof (QueryParser).GetConstructor(new System.Type[] {typeof (ICharStream)}),
|
|||
|
"please switch public QueryParser(CharStream) to be protected");
|
|||
|
|
|||
|
// Same for the constructor for the constructor with the query parser token manager.
|
|||
|
Assert.IsNull(typeof(QueryParser).GetConstructor(new System.Type[] { typeof(QueryParserTokenManager) }),
|
|||
|
"please switch public QueryParser(QueryParserTokenManager) to be protected");
|
|||
|
}
|
|||
|
|
|||
|
[Test]
|
|||
|
public void TestVersioningOfJavaDateRangeBehavior()
|
|||
|
{
|
|||
|
var startDate = GetLocalizedDate(2002, 1, 1, false);
|
|||
|
var endDate = GetLocalizedDate(2002, 1, 4, false);
|
|||
|
|
|||
|
System.Globalization.Calendar calendar = new System.Globalization.GregorianCalendar();
|
|||
|
var endDateExpected = new DateTime(2002, 1, 4, 23, 59, 59, 999, calendar);
|
|||
|
|
|||
|
var qp = new QueryParser(Version.LUCENE_24, "field", new SimpleAnalyzer());
|
|||
|
|
|||
|
// Don't set any date resolution and verify if DateField is used
|
|||
|
AssertDateRangeQueryEquals(qp, "default", startDate, endDate, endDateExpected, null);
|
|||
|
|
|||
|
// Use dates with dashes in them, which aren't parsed out as dates in Java
|
|||
|
AssertDateRangeQueryEquals(qp, "default", "2002-1-1", "2002-1-4", endDateExpected, null);
|
|||
|
|
|||
|
qp = new QueryParser(Version.LUCENE_CURRENT, "field", new SimpleAnalyzer());
|
|||
|
|
|||
|
// We still want to make sure that a localized date of "M/d/YYYY" will be parsed out
|
|||
|
// as a datefield as expected.
|
|||
|
AssertDateRangeQueryEquals(qp, "default", startDate, endDate, endDateExpected, null);
|
|||
|
|
|||
|
// This should be a normal query, NOT a date query if we're emulating Java (on or above Version LUCENE_30)
|
|||
|
AssertQueryEquals(qp, "field", "default:[2002-1-1 TO 2002-1-4]", "default:[2002-1-1 TO 2002-1-4]");
|
|||
|
}
|
|||
|
|
|||
|
// LUCENENET-478: The QueryParser hadn't been updated in so long
|
|||
|
// it had an issue where stopwords inside of phrase queries
|
|||
|
// would be given a null query instead of skipped when EnablePositionIncrements
|
|||
|
// was set to false, so a ToString() on the query would make a query of "Query With Stopwords"
|
|||
|
// into "Query ? Stopwords", regardless of request behavior of position increments
|
|||
|
[Test]
|
|||
|
public void TestStopWordsInPhraseQuery()
|
|||
|
{
|
|||
|
var qp = new QueryParser(Version.LUCENE_CURRENT, "a", new StopAnalyzer(Version.LUCENE_CURRENT));
|
|||
|
|
|||
|
var result = qp.Parse("\"Query With Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query ? stopwords\"", result.ToString());
|
|||
|
|
|||
|
result = qp.Parse("\"Query OR Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query ? stopwords\"", result.ToString());
|
|||
|
|
|||
|
result = qp.Parse("\"Query and Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query ? stopwords\"", result.ToString());
|
|||
|
|
|||
|
result = qp.Parse("\"Query AND Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query ? stopwords\"", result.ToString());
|
|||
|
|
|||
|
// Disable position increments to attempt to remove ? from PhraseQuery.ToString()
|
|||
|
qp.EnablePositionIncrements = false;
|
|||
|
|
|||
|
result = qp.Parse("\"Query With Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query stopwords\"", result.ToString());
|
|||
|
|
|||
|
result = qp.Parse("\"Query OR Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query stopwords\"", result.ToString());
|
|||
|
|
|||
|
result = qp.Parse("\"Query and Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query stopwords\"", result.ToString());
|
|||
|
|
|||
|
result = qp.Parse("\"Query AND Stopwords\"");
|
|||
|
Assert.IsNotNull(result);
|
|||
|
Assert.IsTrue(result is PhraseQuery);
|
|||
|
Assert.AreEqual("a:\"query stopwords\"", result.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|