public override Query Rewrite(IndexReader reader) { Query orig = new RegexQuery(term).Rewrite(reader); // RegexQuery (via MultiTermQuery).rewrite always returns a BooleanQuery BooleanQuery bq = (BooleanQuery)orig; BooleanClause[] clauses = bq.GetClauses(); SpanQuery[] sqs = new SpanQuery[clauses.Length]; for (int i = 0; i < clauses.Length; i++) { BooleanClause clause = clauses[i]; // Clauses from RegexQuery.rewrite are always TermQuery's TermQuery tq = (TermQuery)clause.GetQuery(); sqs[i] = new SpanTermQuery(tq.GetTerm()); sqs[i].SetBoost(tq.GetBoost()); } SpanOrQuery query = new SpanOrQuery(sqs); query.SetBoost(orig.GetBoost()); return(query); }
public virtual void TestNoPayload() { BoostingTermQuery q1 = new BoostingTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "zero")); BoostingTermQuery q2 = new BoostingTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "foo")); BooleanClause c1 = new BooleanClause(q1, BooleanClause.Occur.MUST); BooleanClause c2 = new BooleanClause(q2, BooleanClause.Occur.MUST_NOT); BooleanQuery query = new BooleanQuery(); query.Add(c1); query.Add(c2); TopDocs hits = searcher.Search(query, null, 100); Assert.IsTrue(hits != null, "hits is null and it shouldn't be"); Assert.IsTrue(hits.TotalHits == 1, "hits Size: " + hits.TotalHits + " is not: " + 1); int[] results = new int[1]; results[0] = 0; //hits.scoreDocs[0].doc; CheckHits.CheckHitCollector(query, PayloadHelper.NO_PAYLOAD_FIELD, searcher, results); }
/// <summary> Parses a query, searching on the fields specified. /// Use this if you need to specify certain fields as required, /// and others as prohibited. /// <p><pre> /// Usage: /// <code> /// String[] query = {"query1", "query2", "query3"}; /// String[] fields = {"filename", "contents", "description"}; /// BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD, /// BooleanClause.Occur.MUST, /// BooleanClause.Occur.MUST_NOT}; /// MultiFieldQueryParser.parse(query, fields, flags, analyzer); /// </code> /// </pre> /// <p> /// The code above would construct a query: /// <pre> /// <code> /// (filename:query1) +(contents:query2) -(description:query3) /// </code> /// </pre> /// /// </summary> /// <param name="queries">Queries string to parse /// </param> /// <param name="fields">Fields to search on /// </param> /// <param name="flags">Flags describing the fields /// </param> /// <param name="analyzer">Analyzer to use /// </param> /// <throws> ParseException if query parsing fails </throws> /// <throws> TokenMgrError if query parsing fails </throws> /// <throws> IllegalArgumentException if the length of the queries, fields, </throws> /// <summary> and flags array differ /// </summary> public static Query Parse(System.String[] queries, System.String[] fields, BooleanClause.Occur[] flags, Analyzer analyzer) { if (!(queries.Length == fields.Length && queries.Length == flags.Length)) throw new System.ArgumentException("queries, fields, and flags array have have different length"); BooleanQuery bQuery = new BooleanQuery(); for (int i = 0; i < fields.Length; i++) { QueryParser qp = new QueryParser(fields[i], analyzer); Query q = qp.Parse(queries[i]); bQuery.Add(q, flags[i]); } return bQuery; }
/// <summary> Parses a query, searching on the fields specified. /// Use this if you need to specify certain fields as required, /// and others as prohibited. /// <p><pre> /// Usage: /// <code> /// String[] fields = {"filename", "contents", "description"}; /// BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD, /// BooleanClause.Occur.MUST, /// BooleanClause.Occur.MUST_NOT}; /// MultiFieldQueryParser.parse("query", fields, flags, analyzer); /// </code> /// </pre> /// <p> /// The code above would construct a query: /// <pre> /// <code> /// (filename:query) +(contents:query) -(description:query) /// </code> /// </pre> /// /// </summary> /// <param name="query">Query string to parse /// </param> /// <param name="fields">Fields to search on /// </param> /// <param name="flags">Flags describing the fields /// </param> /// <param name="analyzer">Analyzer to use /// </param> /// <throws> ParseException if query parsing fails </throws> /// <throws> TokenMgrError if query parsing fails </throws> /// <throws> IllegalArgumentException if the length of the fields array differs </throws> /// <summary> from the length of the flags array /// </summary> public static Query Parse(System.String query, System.String[] fields, BooleanClause.Occur[] flags, Analyzer analyzer) { if (fields.Length != flags.Length) throw new System.ArgumentException("fields.length != flags.length"); BooleanQuery bQuery = new BooleanQuery(); for (int i = 0; i < fields.Length; i++) { QueryParser qp = new QueryParser(fields[i], analyzer); Query q = qp.Parse(query); bQuery.Add(q, flags[i]); } return bQuery; }
public virtual void TestNoPayload() { BoostingTermQuery q1 = new BoostingTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "zero")); BoostingTermQuery q2 = new BoostingTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "foo")); BooleanClause c1 = new BooleanClause(q1, BooleanClause.Occur.MUST); BooleanClause c2 = new BooleanClause(q2, BooleanClause.Occur.MUST_NOT); BooleanQuery query = new BooleanQuery(); query.Add(c1); query.Add(c2); TopDocs hits = searcher.Search(query, null, 100); Assert.IsTrue(hits != null, "hits is null and it shouldn't be"); Assert.IsTrue(hits.totalHits == 1, "hits Size: " + hits.totalHits + " is not: " + 1); int[] results = new int[1]; results[0] = 0; //hits.scoreDocs[0].doc; CheckHits.CheckHitCollector(query, PayloadHelper.NO_PAYLOAD_FIELD, searcher, results); }
/// <summary> Builds a new BooleanClause instance</summary> /// <param name="q">sub query /// </param> /// <param name="occur">how this clause should occur when matching documents /// </param> /// <returns> new BooleanClause instance /// </returns> protected internal virtual BooleanClause NewBooleanClause(Query q, BooleanClause.Occur occur) { return new BooleanClause(q, occur); }
public static Lucene.Net.Search.Query ConvertQueryToLuceneQuery(Query query) { if (query == null) { throw new ArgumentNullException("query"); } Lucene.Net.Search.Query lQuery; if (query is MatchAllDocsQuery) { var lMatchAllDocsQuery = new Lucene.Net.Search.MatchAllDocsQuery(); lQuery = lMatchAllDocsQuery; } else if (query is TermQuery) { var termQuery = query as TermQuery; var term = Term.ConvertToLuceneTerm(termQuery.Term); lQuery = new Lucene.Net.Search.TermQuery(term); } else if (query is TermRangeQuery) { var termRangeQuery = query as TermRangeQuery; var lTermRangeQuery = new Lucene.Net.Search.TermRangeQuery(termRangeQuery.FieldName, termRangeQuery.LowerTerm, termRangeQuery.UpperTerm, termRangeQuery.LowerInclusive, termRangeQuery.UpperInclusive); lQuery = lTermRangeQuery; } else if (query is PhraseQuery) { var phraseQuery = query as PhraseQuery; var lPhraseQuery = new Lucene.Net.Search.PhraseQuery(); foreach (var term in phraseQuery.Terms) { var lTerm = Term.ConvertToLuceneTerm(term); lPhraseQuery.Add(lTerm); } if (phraseQuery.Slop.HasValue) { lPhraseQuery.Slop = phraseQuery.Slop.Value; } lQuery = lPhraseQuery; } else if (query is PrefixQuery) { var prefixQuery = query as PrefixQuery; var term = Term.ConvertToLuceneTerm(prefixQuery.Term); var lPrefixQuery = new Lucene.Net.Search.PrefixQuery(term); lQuery = lPrefixQuery; } else if (query is RegexQuery) { var regexQuery = query as RegexQuery; var term = Term.ConvertToLuceneTerm(regexQuery.Term); var lRegexQuery = new Contrib.Regex.RegexQuery(term); lQuery = lRegexQuery; } else if (query is FuzzyQuery) { var fuzzyQuery = query as FuzzyQuery; var term = Term.ConvertToLuceneTerm(fuzzyQuery.Term); var lFuzzyQuery = new Lucene.Net.Search.FuzzyQuery(term); lQuery = lFuzzyQuery; } else if (query is BooleanQuery) { var booleanQuery = query as BooleanQuery; var lBooleanQuery = new Lucene.Net.Search.BooleanQuery(); foreach (var clause in booleanQuery.Clauses) { var lNestedQuery = Query.ConvertQueryToLuceneQuery(clause.Query); Lucene.Net.Search.Occur lOccur; switch (clause.Occur) { case Occur.Must: lOccur = Lucene.Net.Search.Occur.MUST; break; case Occur.MustNot: lOccur = Lucene.Net.Search.Occur.MUST_NOT; break; case Occur.Should: lOccur = Lucene.Net.Search.Occur.SHOULD; break; default: throw new InvalidOperationException("Occur not implemented or defined."); } var lClause = new Lucene.Net.Search.BooleanClause(lNestedQuery, lOccur); lBooleanQuery.Add(lClause); } if (booleanQuery.MinimumNumberShouldMatch.HasValue) { lBooleanQuery.MinimumNumberShouldMatch = booleanQuery.MinimumNumberShouldMatch.Value; } lQuery = lBooleanQuery; } else if (query is WildcardQuery) { var wildcardQuery = query as WildcardQuery; var lTerm = Term.ConvertToLuceneTerm(wildcardQuery.Term); var lWildcardQuery = new Lucene.Net.Search.WildcardQuery(lTerm); lQuery = lWildcardQuery; } else if (query is DoubleNumericRangeQuery) { var doubleNumericRangeQuery = query as DoubleNumericRangeQuery; var ldoubleNumericRangeQuery = Lucene.Net.Search.NumericRangeQuery.NewDoubleRange( doubleNumericRangeQuery.FieldName, doubleNumericRangeQuery.Min, doubleNumericRangeQuery.Max, doubleNumericRangeQuery.MinInclusive, doubleNumericRangeQuery.MaxInclusive); lQuery = ldoubleNumericRangeQuery; } else if (query is FloatNumericRangeQuery) { var floatNumericRangeQuery = query as FloatNumericRangeQuery; var lfloatNumericRangeQuery = Lucene.Net.Search.NumericRangeQuery.NewFloatRange( floatNumericRangeQuery.FieldName, floatNumericRangeQuery.Min, floatNumericRangeQuery.Max, floatNumericRangeQuery.MinInclusive, floatNumericRangeQuery.MaxInclusive); lQuery = lfloatNumericRangeQuery; } else if (query is IntNumericRangeQuery) { var intNumericRangeQuery = query as IntNumericRangeQuery; var lintNumericRangeQuery = Lucene.Net.Search.NumericRangeQuery.NewIntRange( intNumericRangeQuery.FieldName, intNumericRangeQuery.Min, intNumericRangeQuery.Max, intNumericRangeQuery.MinInclusive, intNumericRangeQuery.MaxInclusive); lQuery = lintNumericRangeQuery; } else if (query is LongNumericRangeQuery) { var longNumericRangeQuery = query as LongNumericRangeQuery; var llongNumericRangeQuery = Lucene.Net.Search.NumericRangeQuery.NewLongRange( longNumericRangeQuery.FieldName, longNumericRangeQuery.Min, longNumericRangeQuery.Max, longNumericRangeQuery.MinInclusive, longNumericRangeQuery.MaxInclusive); lQuery = llongNumericRangeQuery; } else if (query is QueryParserQuery) { var queryParserQuery = query as QueryParserQuery; var queryParser = new Lucene.Net.QueryParsers.QueryParser(Version.LUCENE_30, queryParserQuery.DefaultField, new StandardAnalyzer(Version.LUCENE_30)) { AllowLeadingWildcard = queryParserQuery.AllowLeadingWildcard }; lQuery = queryParser.Parse(queryParserQuery.Query); } else if (query is MultiFieldQueryParserQuery) { var multiFieldQueryParserQuery = query as MultiFieldQueryParserQuery; if (multiFieldQueryParserQuery.FieldNames == null) { multiFieldQueryParserQuery.FieldNames = new List <string>(); } var queryParser = new Lucene.Net.QueryParsers.MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, multiFieldQueryParserQuery.FieldNames.ToArray(), new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)); lQuery = queryParser.Parse(multiFieldQueryParserQuery.Query); } else { throw new ArgumentException(@"Unknown or invalid query object", "query"); } if (query.Boost.HasValue) { lQuery.Boost = query.Boost.Value; } return(lQuery); }
/// <summary> /// Creates a query from the analysis chain. /// <p> /// Expert: this is more useful for subclasses such as queryparsers. /// If using this class directly, just use <seealso cref="#createBooleanQuery(String, String)"/> /// and <seealso cref="#createPhraseQuery(String, String)"/> </summary> /// <param name="analyzer"> analyzer used for this query </param> /// <param name="operator"> default boolean operator used for this query </param> /// <param name="field"> field to create queries against </param> /// <param name="queryText"> text to be passed to the analysis chain </param> /// <param name="quoted"> true if phrases should be generated when terms occur at more than one position </param> /// <param name="phraseSlop"> slop factor for phrase/multiphrase queries </param> protected internal Query CreateFieldQuery(Analyzer analyzer, BooleanClause.Occur @operator, string field, string queryText, bool quoted, int phraseSlop) { Debug.Assert(@operator == BooleanClause.Occur.SHOULD || @operator == BooleanClause.Occur.MUST); // Use the analyzer to get all the tokens, and then build a TermQuery, // PhraseQuery, or nothing based on the term count CachingTokenFilter buffer = null; ITermToBytesRefAttribute termAtt = null; IPositionIncrementAttribute posIncrAtt = null; int numTokens = 0; int positionCount = 0; bool severalTokensAtSamePosition = false; bool hasMoreTokens = false; TokenStream source = null; try { source = analyzer.TokenStream(field, new StringReader(queryText)); source.Reset(); buffer = new CachingTokenFilter(source); buffer.Reset(); if (buffer.HasAttribute<ITermToBytesRefAttribute>()) { termAtt = buffer.GetAttribute<ITermToBytesRefAttribute>(); } if (buffer.HasAttribute<IPositionIncrementAttribute>()) { posIncrAtt = buffer.GetAttribute<IPositionIncrementAttribute>(); } if (termAtt != null) { try { hasMoreTokens = buffer.IncrementToken(); while (hasMoreTokens) { numTokens++; int positionIncrement = (posIncrAtt != null) ? posIncrAtt.PositionIncrement : 1; if (positionIncrement != 0) { positionCount += positionIncrement; } else { severalTokensAtSamePosition = true; } hasMoreTokens = buffer.IncrementToken(); } } catch (System.IO.IOException) { // ignore } } } catch (System.IO.IOException e) { throw new Exception("Error analyzing query text", e); } finally { IOUtils.CloseWhileHandlingException(source); } // rewind the buffer stream buffer.Reset(); BytesRef bytes = termAtt == null ? null : termAtt.BytesRef; if (numTokens == 0) { return null; } else if (numTokens == 1) { try { bool hasNext = buffer.IncrementToken(); Debug.Assert(hasNext == true); termAtt.FillBytesRef(); } catch (System.IO.IOException) { // safe to ignore, because we know the number of tokens } return NewTermQuery(new Term(field, BytesRef.DeepCopyOf(bytes))); } else { if (severalTokensAtSamePosition || (!quoted)) { if (positionCount == 1 || (!quoted)) { // no phrase query: if (positionCount == 1) { // simple case: only one position, with synonyms BooleanQuery q = NewBooleanQuery(true); for (int i = 0; i < numTokens; i++) { try { bool hasNext = buffer.IncrementToken(); Debug.Assert(hasNext == true); termAtt.FillBytesRef(); } catch (System.IO.IOException) { // safe to ignore, because we know the number of tokens } Query currentQuery = NewTermQuery(new Term(field, BytesRef.DeepCopyOf(bytes))); q.Add(currentQuery, BooleanClause.Occur.SHOULD); } return q; } else { // multiple positions BooleanQuery q = NewBooleanQuery(false); Query currentQuery = null; for (int i = 0; i < numTokens; i++) { try { bool hasNext = buffer.IncrementToken(); Debug.Assert(hasNext == true); termAtt.FillBytesRef(); } catch (System.IO.IOException) { // safe to ignore, because we know the number of tokens } if (posIncrAtt != null && posIncrAtt.PositionIncrement == 0) { if (!(currentQuery is BooleanQuery)) { Query t = currentQuery; currentQuery = NewBooleanQuery(true); ((BooleanQuery)currentQuery).Add(t, BooleanClause.Occur.SHOULD); } ((BooleanQuery)currentQuery).Add(NewTermQuery(new Term(field, BytesRef.DeepCopyOf(bytes))), BooleanClause.Occur.SHOULD); } else { if (currentQuery != null) { q.Add(currentQuery, @operator); } currentQuery = NewTermQuery(new Term(field, BytesRef.DeepCopyOf(bytes))); } } q.Add(currentQuery, @operator); return q; } } else { // phrase query: MultiPhraseQuery mpq = NewMultiPhraseQuery(); mpq.Slop = phraseSlop; IList<Term> multiTerms = new List<Term>(); int position = -1; for (int i = 0; i < numTokens; i++) { int positionIncrement = 1; try { bool hasNext = buffer.IncrementToken(); Debug.Assert(hasNext == true); termAtt.FillBytesRef(); if (posIncrAtt != null) { positionIncrement = posIncrAtt.PositionIncrement; } } catch (System.IO.IOException) { // safe to ignore, because we know the number of tokens } if (positionIncrement > 0 && multiTerms.Count > 0) { if (EnablePositionIncrements_Renamed) { mpq.Add(multiTerms.ToArray(), position); } else { mpq.Add(multiTerms.ToArray()); } multiTerms.Clear(); } position += positionIncrement; multiTerms.Add(new Term(field, BytesRef.DeepCopyOf(bytes))); } if (EnablePositionIncrements_Renamed) { mpq.Add(multiTerms.ToArray(), position); } else { mpq.Add(multiTerms.ToArray()); } return mpq; } } else { PhraseQuery pq = NewPhraseQuery(); pq.Slop = phraseSlop; int position = -1; for (int i = 0; i < numTokens; i++) { int positionIncrement = 1; try { bool hasNext = buffer.IncrementToken(); Debug.Assert(hasNext == true); termAtt.FillBytesRef(); if (posIncrAtt != null) { positionIncrement = posIncrAtt.PositionIncrement; } } catch (System.IO.IOException) { // safe to ignore, because we know the number of tokens } if (EnablePositionIncrements_Renamed) { position += positionIncrement; pq.Add(new Term(field, BytesRef.DeepCopyOf(bytes)), position); } else { pq.Add(new Term(field, BytesRef.DeepCopyOf(bytes))); } } return pq; } } }
/// <summary> /// Creates a boolean query from the query text. /// <p> </summary> /// <param name="field"> field name </param> /// <param name="queryText"> text to be passed to the analyzer </param> /// <param name="operator"> operator used for clauses between analyzer tokens. </param> /// <returns> {@code TermQuery} or {@code BooleanQuery}, based on the analysis /// of {@code queryText} </returns> public virtual Query CreateBooleanQuery(string field, string queryText, BooleanClause.Occur @operator) { if (@operator != BooleanClause.Occur.SHOULD && @operator != BooleanClause.Occur.MUST) { throw new System.ArgumentException("invalid operator: only SHOULD or MUST are allowed"); } return CreateFieldQuery(Analyzer_Renamed, @operator, field, queryText, false, 0); }
/// <summary> Parses a query, searching on the fields specified. Use this if you need /// to specify certain fields as required, and others as prohibited. /// <p/> /// /// <pre> /// Usage: /// <code> /// String[] query = {"query1", "query2", "query3"}; /// String[] fields = {"filename", "contents", "description"}; /// BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD, /// BooleanClause.Occur.MUST, /// BooleanClause.Occur.MUST_NOT}; /// MultiFieldQueryParser.parse(query, fields, flags, analyzer); /// </code> /// </pre> /// <p/> /// The code above would construct a query: /// /// <pre> /// <code> /// (filename:query1) +(contents:query2) -(description:query3) /// </code> /// </pre> /// /// </summary> /// <param name="matchVersion">Lucene version to match; this is passed through to /// QueryParser. /// </param> /// <param name="queries">Queries string to parse /// </param> /// <param name="fields">Fields to search on /// </param> /// <param name="flags">Flags describing the fields /// </param> /// <param name="analyzer">Analyzer to use /// </param> /// <throws> ParseException </throws> /// <summary> if query parsing fails /// </summary> /// <throws> IllegalArgumentException </throws> /// <summary> if the length of the queries, fields, and flags array differ /// </summary> public static Query Parse(Version matchVersion, System.String[] queries, System.String[] fields, BooleanClause.Occur[] flags, Analyzer analyzer) { if (!(queries.Length == fields.Length && queries.Length == flags.Length)) throw new System.ArgumentException("queries, fields, and flags array have have different length"); BooleanQuery bQuery = new BooleanQuery(); for (int i = 0; i < fields.Length; i++) { QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer); Query q = qp.Parse(queries[i]); if (q != null && (!(q is BooleanQuery) || ((BooleanQuery) q).GetClauses().Length > 0)) { bQuery.Add(q, flags[i]); } } return bQuery; }
public static Query Parse(System.String[] queries, System.String[] fields, BooleanClause.Occur[] flags, Analyzer analyzer) { return Parse(Version.LUCENE_24, queries, fields, flags, analyzer); }