| /* |
| * 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.GetSet<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()); |
| } |
| } |
| } |