예제 #1
0
        int termOrPhraseNumber; // used for colored tag support

        public FieldQuery(Query query, bool phraseHighlight, bool fieldMatch)
        {
            this.fieldMatch = fieldMatch;
            Dictionary <Query, Query> flatQueries = new Dictionary <Query, Query>();

            flatten(query, flatQueries);
            SaveTerms(flatQueries);
            Dictionary <Query, Query> expandQueries = expand(flatQueries);

            foreach (Query flatQuery in expandQueries.Keys)
            {
                QueryPhraseMap rootMap = getRootMap(flatQuery);
                rootMap.Add(flatQuery);
                if (!phraseHighlight && flatQuery is PhraseQuery)
                {
                    PhraseQuery pq = (PhraseQuery)flatQuery;
                    if (pq.GetTerms().Length > 1)
                    {
                        foreach (Term term in pq.GetTerms())
                        {
                            rootMap.AddTerm(term.Text, flatQuery.Boost);
                        }
                    }
                }
            }
        }
예제 #2
0
        internal FieldQuery(Query query, IndexReader reader, bool phraseHighlight, bool fieldMatch)
        {
            this.fieldMatch = fieldMatch;
            // LUCENENET NOTE: LinkedHashSet cares about insertion order
            ISet <Query> flatQueries = new JCG.LinkedHashSet <Query>();

            Flatten(query, reader, flatQueries);
            SaveTerms(flatQueries, reader);
            ICollection <Query> expandQueries = Expand(flatQueries);

            foreach (Query flatQuery in expandQueries)
            {
                QueryPhraseMap rootMap = GetRootMap(flatQuery);
                rootMap.Add(flatQuery, reader);
                if (!phraseHighlight && flatQuery is PhraseQuery)
                {
                    PhraseQuery pq = (PhraseQuery)flatQuery;
                    if (pq.GetTerms().Length > 1)
                    {
                        foreach (Term term in pq.GetTerms())
                        {
                            rootMap.AddTerm(term, flatQuery.Boost);
                        }
                    }
                }
            }
        }
예제 #3
0
 /// <summary>
 /// Return 'key' string. 'key' is the field name of the <see cref="Query"/>.
 /// If not fieldMatch, 'key' will be null.
 /// </summary>
 private string GetKey(Query query)
 {
     if (!fieldMatch)
     {
         return(null);
     }
     if (query is TermQuery)
     {
         return(((TermQuery)query).Term.Field);
     }
     else if (query is PhraseQuery)
     {
         PhraseQuery pq    = (PhraseQuery)query;
         Term[]      terms = pq.GetTerms();
         return(terms[0].Field);
     }
     else if (query is MultiTermQuery)
     {
         return(((MultiTermQuery)query).Field);
     }
     else
     {
         throw new Exception("query \"" + query.ToString() + "\" must be flatten first.");
     }
 }
예제 #4
0
        public override Query VisitPhraseQuery(PhraseQuery phraseq)
        {
            var terms = phraseq.GetTerms();
            PhraseQuery newQuery = null;

            var index = 0;
            var count = terms.Length;
            while (index < count)
            {
                var visitedTerm = VisitTerm(terms[index]);
                if (newQuery != null)
                {
                    if (visitedTerm != null)
                        newQuery.Add(visitedTerm);
                }
                else if (visitedTerm != terms[index])
                {
                    newQuery = new PhraseQuery();
                    for (var i = 0; i < index; i++)
                        newQuery.Add(terms[i]);
                    if (visitedTerm != null)
                        newQuery.Add(visitedTerm);
                }
                index++;
            }
            if (newQuery != null)
            {
                if (newQuery.GetTerms().Length > 0)
                    return newQuery;
                return null;
            }
            return phraseq;
        }
예제 #5
0
        public virtual Query VisitPhraseQuery(PhraseQuery phraseq)
        {
            var         terms    = phraseq.GetTerms();
            PhraseQuery newQuery = null;

            int index = 0;
            int count = terms.Length;

            while (index < count)
            {
                var visitedTerm = VisitTerm(terms[index]);
                if (newQuery != null)
                {
                    newQuery.Add(visitedTerm);
                }
                else if (visitedTerm != terms[index])
                {
                    newQuery = new PhraseQuery();
                    for (int i = 0; i < index; i++)
                    {
                        newQuery.Add(terms[i]);
                    }
                    newQuery.Add(visitedTerm);
                }
                index++;
            }
            if (newQuery != null)
            {
                return(newQuery);
            }
            return(phraseq);
        }
예제 #6
0
        private BsonDocument VisitPhrase(PhraseQuery phraseQuery)
        {
            var terms = phraseQuery.GetTerms();

            var doc = new BsonDocument
            {
                ["path"] = GetPath(terms[0].Field),
            };

            if (terms.Length == 1)
            {
                doc["query"] = terms[0].Text;
            }
            else
            {
                doc["query"] = new BsonArray(terms.Select(x => x.Text));
            }

            if (phraseQuery.Slop != 0)
            {
                doc["slop"] = phraseQuery.Slop;
            }

            ApplyBoost(phraseQuery, doc);

            return(new BsonDocument
            {
                ["phrase"] = doc
            });
        }
예제 #7
0
        /*
         * Return 'key' string. 'key' is the field name of the Query.
         * If not fieldMatch, 'key' will be null.
         */
        private String GetKey(Query query)
        {
            if (!fieldMatch)
            {
                return(null);
            }
            if (query is TermQuery)
            {
                return(((TermQuery)query).Term.Field);
            }

            if (query is PrefixQuery)
            {
                return(((PrefixQuery)query).Prefix.Field);
            }

            if (query is PhraseQuery)
            {
                PhraseQuery pq    = (PhraseQuery)query;
                Term[]      terms = pq.GetTerms();
                return(terms[0].Field);
            }

            throw new ApplicationException("query \"" + query + "\" must be flatten first.");
        }
예제 #8
0
 public void Add(Query query)
 {
     if (query is TermQuery)
     {
         AddTerm(((TermQuery)query).Term.Text, query.Boost);
     }
     else if (query is PrefixQuery)
     {
         AddTerm(((PrefixQuery)query).Prefix.Text + "*", query.Boost);
     }
     else if (query is PhraseQuery)
     {
         PhraseQuery pq    = (PhraseQuery)query;
         Term[]      terms = pq.GetTerms();
         HashMap <String, QueryPhraseMap> map = subMap;
         QueryPhraseMap qpm = null;
         foreach (Term term in terms)
         {
             qpm = GetOrNewMap(map, term.Text);
             map = qpm.subMap;
         }
         qpm.MarkTerminal(pq.Slop, pq.Boost);
     }
     else
     {
         throw new ApplicationException("query \"" + query.ToString() + "\" must be flatten first.");
     }
 }
예제 #9
0
 private static void VisitQuery(PhraseQuery query, AzureQueryLogger.IndentedTextWriter writer)
 {
     writer.WriteLine("Slop: {0}", (object)query.Slop);
     foreach (Term term in query.GetTerms())
     {
         AzureQueryLogger.VisitTerm(term, writer);
     }
 }
예제 #10
0
 /*
  * Check if PhraseQuery A and B have overlapped part.
  * 
  * ex1) A="a b", B="b c" => overlap; expandQueries={"a b c"}
  * ex2) A="b c", B="a b" => overlap; expandQueries={"a b c"}
  * ex3) A="a b", B="c d" => no overlap; expandQueries={}
  */
 private void CheckOverlap(Dictionary<Query,Query> expandQueries, PhraseQuery a, PhraseQuery b)
 {
     if (a.GetSlop() != b.GetSlop()) return;
     Term[] ats = a.GetTerms();
     Term[] bts = b.GetTerms();
     if (fieldMatch && !ats[0].Field().Equals(bts[0].Field())) return;
     CheckOverlap(expandQueries, ats, bts, a.GetSlop(), a.GetBoost());
     CheckOverlap(expandQueries, bts, ats, b.GetSlop(), b.GetBoost());
 }
예제 #11
0
 public void flatten(Query sourceQuery, Dictionary<Query,Query> flatQueries)
 {
     if (sourceQuery is BooleanQuery)
     {
         BooleanQuery bq = (BooleanQuery)sourceQuery;
         foreach (BooleanClause clause in bq.GetClauses())
         {
             if (!clause.IsProhibited())
                 flatten(clause.GetQuery(), flatQueries);
         }
     }
     else if (sourceQuery is DisjunctionMaxQuery)
     {
         DisjunctionMaxQuery dmq = (DisjunctionMaxQuery)sourceQuery;
         System.Collections.IEnumerator en = dmq.Iterator();
         while (en.MoveNext())
         {
             Query query = (Query)en.Current;
             flatten(query, flatQueries);
         }
     }
     else if (sourceQuery is TermQuery)
     {
         if (!flatQueries.ContainsKey(sourceQuery))
             flatQueries.Add(sourceQuery, sourceQuery);
     }
     else if (sourceQuery is PhraseQuery)
     {
         if (!flatQueries.ContainsKey(sourceQuery))
         {
             PhraseQuery pq = (PhraseQuery)sourceQuery;
             if (pq.GetTerms().Length > 1)
                 flatQueries.Add(pq, pq);
             else if (pq.GetTerms().Length == 1)
             {
                 Query q = new TermQuery(pq.GetTerms()[0]);
                 flatQueries.Add(q, q);
             }
         }
     }
     // else discard queries
 }
 private SectionSearchQueryPlan TranslatePhraseQuery(PhraseQuery query)
 {
     Term[]     terms     = query.GetTerms();
     TermNode[] nodes     = new TermNode[terms.Length];
     int[]      positions = query.GetPositions();
     for (int i = 0; i < terms.Length; i++)
     {
         nodes[i] = new TermNode(terms[i], positions[i], m_reader);
     }
     return(new PhraseNode(nodes, m_reader));
 }
예제 #13
0
 /*
  * Return 'key' string. 'key' is the field name of the Query.
  * If not fieldMatch, 'key' will be null.
  */
 private String GetKey(Query query)
 {
     if (!fieldMatch) return null;
     if (query is TermQuery)
         return ((TermQuery)query).GetTerm().Field();
     else if (query is PhraseQuery)
     {
         PhraseQuery pq = (PhraseQuery)query;
         Term[] terms = pq.GetTerms();
         return terms[0].Field();
     }
     else
         throw new System.ApplicationException("query \"" + query.ToString() + "\" must be flatten first.");
 }
예제 #14
0
 /*
  * Check if PhraseQuery A and B have overlapped part.
  *
  * ex1) A="a b", B="b c" => overlap; expandQueries={"a b c"}
  * ex2) A="b c", B="a b" => overlap; expandQueries={"a b c"}
  * ex3) A="a b", B="c d" => no overlap; expandQueries={}
  */
 private void CheckOverlap(Dictionary <Query, Query> expandQueries, PhraseQuery a, PhraseQuery b)
 {
     if (a.Slop != b.Slop)
     {
         return;
     }
     Term[] ats = a.GetTerms();
     Term[] bts = b.GetTerms();
     if (fieldMatch && !ats[0].Field.Equals(bts[0].Field))
     {
         return;
     }
     CheckOverlap(expandQueries, ats, bts, a.Slop, a.Boost);
     CheckOverlap(expandQueries, bts, ats, b.Slop, b.Boost);
 }
예제 #15
0
 /// <summary>
 /// Check if <see cref="PhraseQuery"/> A and B have overlapped part.
 ///
 /// <code>
 /// ex1) A="a b", B="b c" => overlap; expandQueries={"a b c"}
 /// ex2) A="b c", B="a b" => overlap; expandQueries={"a b c"}
 /// ex3) A="a b", B="c d" => no overlap; expandQueries={}
 /// </code>
 /// </summary>
 private void CheckOverlap(ICollection <Query> expandQueries, PhraseQuery a, PhraseQuery b)
 {
     if (a.Slop != b.Slop)
     {
         return;
     }
     Term[] ats = a.GetTerms();
     Term[] bts = b.GetTerms();
     if (fieldMatch && !ats[0].Field.Equals(bts[0].Field, StringComparison.Ordinal))
     {
         return;
     }
     CheckOverlap(expandQueries, ats, bts, a.Slop, a.Boost);
     CheckOverlap(expandQueries, bts, ats, b.Slop, b.Boost);
 }
예제 #16
0
        public override Query VisitPhraseQuery(PhraseQuery phraseq)
        {
            var terms = phraseq.GetTerms();
            var field = terms[0].Field();

            _text.Append(field);
            _text.Append(":\"");

            var positions = new int[terms.Length];
            for (var i = 0; i < positions.Length; i++)
                positions[i] = i;

            var pieces = new string[terms.Length];
            for (var i = 0; i < terms.Length; i++)
            {
                var pos = positions[i];
                var s = pieces[pos];
                if (s == null)
                    s = (terms[i]).Text();
                else
                    s += "|" + (terms[i]).Text();
                pieces[pos] = s;
            }
            for (var i = 0; i < pieces.Length; i++)
            {
                if (i > 0)
                    _text.Append(' ');
                var s = pieces[i];
                if (s == null)
                    _text.Append('?');
                else
                    _text.Append(s);
            }
            _text.Append("\"");

            var slop = phraseq.GetSlop();
            if (slop != 0)
            {
                _text.Append("~");
                _text.Append(slop);
            }

            _text.Append(BoostToString(phraseq.GetBoost()));

            return base.VisitPhraseQuery(phraseq);
        }
예제 #17
0
        public override Query VisitPhraseQuery(PhraseQuery phraseq)
        {
            _dump.Append("PhraseQ(");

            var         terms    = phraseq.GetTerms();
            PhraseQuery newQuery = null;

            int index = 0;
            int count = terms.Length;

            while (index < count)
            {
                var visitedTerm = VisitTerm(terms[index]);
                if (newQuery != null)
                {
                    newQuery.Add(visitedTerm);
                }
                else if (visitedTerm != terms[index])
                {
                    newQuery = new PhraseQuery();
                    for (int i = 0; i < index; i++)
                    {
                        newQuery.Add(terms[i]);
                    }
                    newQuery.Add(visitedTerm);
                }
                index++;
                if (index < count)
                {
                    _dump.Append(", ");
                }
            }
            _dump.Append(", Slop:").Append(phraseq.GetSlop()).Append(BoostToString(phraseq)).Append(")");
            if (newQuery != null)
            {
                return(newQuery);
            }
            return(phraseq);
        }
예제 #18
0
        private ParameterizedSql BuildPhrase(PhraseQuery phraseQuery)
        {
            var termsAdded         = 0;
            var field              = "";
            var queryStringBuilder = new StringBuilder();

            foreach (var term in phraseQuery.GetTerms())
            {
                if (termsAdded == 0)
                {
                    field = term.Field;
                }
                else if (termsAdded > 0)
                {
                    queryStringBuilder.Append(" ");
                }

                queryStringBuilder.Append(term.Text);

                termsAdded++;
            }

            Query query;
            var   queryString = queryStringBuilder.ToString();

            if (queryString.Contains("?") || queryString.Contains("*"))
            {
                query = new WildcardQuery(new Term(field, queryString));
            }
            else
            {
                query = new TermQuery(new Term(field, queryString));
            }

            return(Build(query));
        }
예제 #19
0
 internal void Add(Query query, IndexReader reader)
 {
     if (query is TermQuery)
     {
         AddTerm(((TermQuery)query).Term, query.Boost);
     }
     else if (query is PhraseQuery)
     {
         PhraseQuery pq    = (PhraseQuery)query;
         Term[]      terms = pq.GetTerms();
         IDictionary <string, QueryPhraseMap> map = subMap;
         QueryPhraseMap qpm = null;
         foreach (Term term in terms)
         {
             qpm = GetOrNewMap(map, term.Text());
             map = qpm.subMap;
         }
         qpm.MarkTerminal(pq.Slop, pq.Boost);
     }
     else
     {
         throw new Exception("query \"" + query.ToString() + "\" must be flatten first.");
     }
 }
예제 #20
0
        public void flatten(Query sourceQuery, Dictionary <Query, Query> flatQueries)
        {
            if (sourceQuery is BooleanQuery)
            {
                BooleanQuery bq = (BooleanQuery)sourceQuery;
                foreach (BooleanClause clause in bq.GetClauses())
                {
                    if (!clause.IsProhibited)
                    {
                        flatten(clause.Query, flatQueries);
                    }
                }
            }
            else if (sourceQuery is PrefixQuery)
            {
                if (!flatQueries.ContainsKey(sourceQuery))
                {
                    flatQueries.Add(sourceQuery, sourceQuery);
                }
            }
            else if (sourceQuery is DisjunctionMaxQuery)
            {
                DisjunctionMaxQuery dmq = (DisjunctionMaxQuery)sourceQuery;
                foreach (Query query in dmq)
                {
                    flatten(query, flatQueries);
                }
            }
            else if (sourceQuery is TermQuery)
            {
                if (!flatQueries.ContainsKey(sourceQuery))
                {
                    flatQueries.Add(sourceQuery, sourceQuery);
                }
            }
            else if (sourceQuery is PhraseQuery)
            {
                if (!flatQueries.ContainsKey(sourceQuery))
                {
                    PhraseQuery pq = (PhraseQuery)sourceQuery;
                    if (pq.GetTerms().Length > 1)
                    {
                        flatQueries.Add(pq, pq);
                    }
                    else if (pq.GetTerms().Length == 1)
                    {
                        Query q = new TermQuery(pq.GetTerms()[0]);
                        flatQueries.Add(q, q);
                    }
                }
            }
            else
            {
                // Fallback to using extracted terms
                ISet <Term> terms = SetFactory.CreateHashSet <Term>();
                try
                {
                    sourceQuery.ExtractTerms(terms);
                }
                catch (NotSupportedException)
                {           // thrown by default impl
                    return; // ignore error and discard query
                }

                foreach (var term in terms)
                {
                    flatten(new TermQuery(term), flatQueries);
                }
            }
        }
        private static string ExtractLuceneClauses(Query query, string inputQuery, List <BooleanClause> luceneClauses)
        {
            BooleanQuery        boolQuery = query as BooleanQuery;
            IEnumerable <Query> clauses   = boolQuery == null ? new[] { query } : boolQuery.Clauses.Select(c => c.Query);

            // Process the query to extract the "nuget query" part and the "lucene filters" part
            StringBuilder nugetQuery = new StringBuilder();

            foreach (Query q in clauses)
            {
                TermQuery tq           = q as TermQuery;
                bool      handledQuery = false;
                if (tq != null && !AllowedNuGetFields.Contains(tq.Term.Field))
                {
                    // Ignore fields we don't accept in NuGet-style queries
                    // And, add in terms that aren't labelled with a field.
                    bool containsWhitespace = tq.Term.Text.Any(Char.IsWhiteSpace);
                    if (containsWhitespace)
                    {
                        nugetQuery.Append("\"");
                    }
                    nugetQuery.Append(tq.Term.Text);
                    if (containsWhitespace)
                    {
                        nugetQuery.Append("\"");
                    }
                    nugetQuery.Append(" ");
                    handledQuery = true;
                }
                else
                {
                    PhraseQuery pq = q as PhraseQuery;
                    if (pq != null)
                    {
                        Term[]   terms      = pq.GetTerms();
                        string[] fieldNames = terms
                                              .Select(t => t.Field)
                                              .Distinct(StringComparer.OrdinalIgnoreCase)
                                              .ToArray();
                        if (fieldNames.Length == 1 && !AllowedNuGetFields.Contains(fieldNames[0]))
                        {
                            // All the terms refer to the same field and it's
                            // not a valid NuGet-style field
                            nugetQuery.AppendFormat("\"{0}\"", String.Join(" ", terms.Select(t => t.Text)));
                            nugetQuery.Append(" ");
                            handledQuery = true;
                        }
                    }
                }

                // Convert the clause to a MUST-have clause
                if (!handledQuery)
                {
                    luceneClauses.Add(new BooleanClause(q, Occur.MUST));
                }
            }

            if (nugetQuery.Length > 0)
            {
                nugetQuery.Length -= 1; // Strip trailing space.
            }
            return(nugetQuery.ToString());
        }
        /// <summary>
        /// Fills a <c>Map</c> with <see cref="WeightedSpanTerm"/>s using the terms from the supplied <c>Query</c>.
        /// </summary>
        /// <param name="query">Query to extract Terms from</param>
        /// <param name="terms">Map to place created WeightedSpanTerms in</param>
        private void Extract(Query query, IDictionary <String, WeightedSpanTerm> terms)
        {
            if (query is BooleanQuery)
            {
                BooleanClause[] queryClauses = ((BooleanQuery)query).GetClauses();

                for (int i = 0; i < queryClauses.Length; i++)
                {
                    if (!queryClauses[i].IsProhibited)
                    {
                        Extract(queryClauses[i].Query, terms);
                    }
                }
            }
            else if (query is PhraseQuery)
            {
                PhraseQuery phraseQuery      = ((PhraseQuery)query);
                Term[]      phraseQueryTerms = phraseQuery.GetTerms();
                SpanQuery[] clauses          = new SpanQuery[phraseQueryTerms.Length];
                for (int i = 0; i < phraseQueryTerms.Length; i++)
                {
                    clauses[i] = new SpanTermQuery(phraseQueryTerms[i]);
                }
                int   slop      = phraseQuery.Slop;
                int[] positions = phraseQuery.GetPositions();
                // add largest position increment to slop
                if (positions.Length > 0)
                {
                    int lastPos    = positions[0];
                    int largestInc = 0;
                    int sz         = positions.Length;
                    for (int i = 1; i < sz; i++)
                    {
                        int pos = positions[i];
                        int inc = pos - lastPos;
                        if (inc > largestInc)
                        {
                            largestInc = inc;
                        }
                        lastPos = pos;
                    }
                    if (largestInc > 1)
                    {
                        slop += largestInc;
                    }
                }

                bool inorder = slop == 0;

                SpanNearQuery sp = new SpanNearQuery(clauses, slop, inorder);
                sp.Boost = query.Boost;
                ExtractWeightedSpanTerms(terms, sp);
            }
            else if (query is TermQuery)
            {
                ExtractWeightedTerms(terms, query);
            }
            else if (query is SpanQuery)
            {
                ExtractWeightedSpanTerms(terms, (SpanQuery)query);
            }
            else if (query is FilteredQuery)
            {
                Extract(((FilteredQuery)query).Query, terms);
            }
            else if (query is DisjunctionMaxQuery)
            {
                foreach (var q in ((DisjunctionMaxQuery)query))
                {
                    Extract(q, terms);
                }
            }
            else if (query is MultiTermQuery && expandMultiTermQuery)
            {
                MultiTermQuery mtq = ((MultiTermQuery)query);
                if (mtq.RewriteMethod != MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE)
                {
                    mtq = (MultiTermQuery)mtq.Clone();
                    mtq.RewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
                    query             = mtq;
                }
                FakeReader fReader = new FakeReader();
                MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE.Rewrite(fReader, mtq);
                if (fReader.Field != null)
                {
                    IndexReader ir = GetReaderForField(fReader.Field);
                    Extract(query.Rewrite(ir), terms);
                }
            }
            else if (query is MultiPhraseQuery)
            {
                MultiPhraseQuery mpq        = (MultiPhraseQuery)query;
                IList <Term[]>   termArrays = mpq.GetTermArrays();
                int[]            positions  = mpq.GetPositions();
                if (positions.Length > 0)
                {
                    int maxPosition = positions[positions.Length - 1];
                    for (int i = 0; i < positions.Length - 1; ++i)
                    {
                        if (positions[i] > maxPosition)
                        {
                            maxPosition = positions[i];
                        }
                    }

                    var disjunctLists     = new List <SpanQuery> [maxPosition + 1];
                    int distinctPositions = 0;

                    for (int i = 0; i < termArrays.Count; ++i)
                    {
                        Term[]           termArray = termArrays[i];
                        List <SpanQuery> disjuncts = disjunctLists[positions[i]];
                        if (disjuncts == null)
                        {
                            disjuncts = (disjunctLists[positions[i]] = new List <SpanQuery>(termArray.Length));
                            ++distinctPositions;
                        }
                        for (int j = 0; j < termArray.Length; ++j)
                        {
                            disjuncts.Add(new SpanTermQuery(termArray[j]));
                        }
                    }

                    int         positionGaps = 0;
                    int         position     = 0;
                    SpanQuery[] clauses      = new SpanQuery[distinctPositions];
                    for (int i = 0; i < disjunctLists.Length; ++i)
                    {
                        List <SpanQuery> disjuncts = disjunctLists[i];
                        if (disjuncts != null)
                        {
                            clauses[position++] = new SpanOrQuery(disjuncts.ToArray());
                        }
                        else
                        {
                            ++positionGaps;
                        }
                    }

                    int  slop    = mpq.Slop;
                    bool inorder = (slop == 0);

                    SpanNearQuery sp = new SpanNearQuery(clauses, slop + positionGaps, inorder);
                    sp.Boost = query.Boost;
                    ExtractWeightedSpanTerms(terms, sp);
                }
            }
        }
예제 #23
0
        public override Query VisitPhraseQuery(PhraseQuery phraseq)
        {
            var terms = phraseq.GetTerms();
            var field = terms[0].Field();

            _text.Append(field);
            _text.Append(":\"");

            var positions = new int[terms.Length];

            for (int i = 0; i < positions.Length; i++)
            {
                positions[i] = i;
            }

            var pieces = new string[terms.Length];

            for (int i = 0; i < terms.Length; i++)
            {
                int           pos = ((System.Int32)positions[i]);
                System.String s   = pieces[pos];
                if (s == null)
                {
                    s = (terms[i]).Text();
                }
                else
                {
                    s += "|" + (terms[i]).Text();
                }
                pieces[pos] = s;
            }
            for (int i = 0; i < pieces.Length; i++)
            {
                if (i > 0)
                {
                    _text.Append(' ');
                }
                System.String s = pieces[i];
                if (s == null)
                {
                    _text.Append('?');
                }
                else
                {
                    _text.Append(s);
                }
            }
            _text.Append("\"");

            var slop = phraseq.GetSlop();

            if (slop != 0)
            {
                _text.Append("~");
                _text.Append(slop);
            }

            _text.Append(BoostToString(phraseq.GetBoost()));

            return(base.VisitPhraseQuery(phraseq));
        }
        /// <summary>
        /// Fills a <see cref="T:IDictionary{string, WeightedSpanTerm}"/> with <see cref="WeightedSpanTerm"/>s using the terms from the supplied <paramref name="query"/>.
        /// </summary>
        /// <param name="query"><see cref="Query"/> to extract Terms from</param>
        /// <param name="terms">Map to place created <see cref="WeightedSpanTerm"/>s in</param>
        /// <exception cref="System.IO.IOException">If there is a low-level I/O error</exception>
        protected virtual void Extract(Query query, IDictionary <string, WeightedSpanTerm> terms)
        {
            if (query is BooleanQuery)
            {
                IList <BooleanClause> queryClauses = ((BooleanQuery)query).Clauses;

                for (int i = 0; i < queryClauses.Count; i++)
                {
                    if (!queryClauses[i].IsProhibited)
                    {
                        Extract(queryClauses[i].Query, terms);
                    }
                }
            }
            else if (query is PhraseQuery)
            {
                PhraseQuery phraseQuery      = (PhraseQuery)query;
                Term[]      phraseQueryTerms = phraseQuery.GetTerms();
                SpanQuery[] clauses          = new SpanQuery[phraseQueryTerms.Length];
                for (int i = 0; i < phraseQueryTerms.Length; i++)
                {
                    clauses[i] = new SpanTermQuery(phraseQueryTerms[i]);
                }
                int   slop      = phraseQuery.Slop;
                int[] positions = phraseQuery.GetPositions();
                // add largest position increment to slop
                if (positions.Length > 0)
                {
                    int lastPos    = positions[0];
                    int largestInc = 0;
                    int sz         = positions.Length;
                    for (int i = 1; i < sz; i++)
                    {
                        int pos = positions[i];
                        int inc = pos - lastPos;
                        if (inc > largestInc)
                        {
                            largestInc = inc;
                        }
                        lastPos = pos;
                    }
                    if (largestInc > 1)
                    {
                        slop += largestInc;
                    }
                }

                bool inorder = slop == 0;

                SpanNearQuery sp = new SpanNearQuery(clauses, slop, inorder);
                sp.Boost = query.Boost;
                ExtractWeightedSpanTerms(terms, sp);
            }
            else if (query is TermQuery)
            {
                ExtractWeightedTerms(terms, query);
            }
            else if (query is SpanQuery)
            {
                ExtractWeightedSpanTerms(terms, (SpanQuery)query);
            }
            else if (query is FilteredQuery)
            {
                Extract(((FilteredQuery)query).Query, terms);
            }
            else if (query is ConstantScoreQuery)
            {
                Query q = ((ConstantScoreQuery)query).Query;
                if (q != null)
                {
                    Extract(q, terms);
                }
            }
            else if (query is CommonTermsQuery)
            {
                // specialized since rewriting would change the result query
                // this query is TermContext sensitive.
                ExtractWeightedTerms(terms, query);
            }
            else if (query is DisjunctionMaxQuery)
            {
                foreach (var q in ((DisjunctionMaxQuery)query))
                {
                    Extract(q, terms);
                }
            }
            else if (query is MultiPhraseQuery)
            {
                MultiPhraseQuery mpq        = (MultiPhraseQuery)query;
                IList <Term[]>   termArrays = mpq.GetTermArrays();
                int[]            positions  = mpq.GetPositions();
                if (positions.Length > 0)
                {
                    int maxPosition = positions[positions.Length - 1];
                    for (int i = 0; i < positions.Length - 1; ++i)
                    {
                        if (positions[i] > maxPosition)
                        {
                            maxPosition = positions[i];
                        }
                    }

                    var disjunctLists     = new List <SpanQuery> [maxPosition + 1];
                    int distinctPositions = 0;

                    for (int i = 0; i < termArrays.Count; ++i)
                    {
                        Term[]           termArray = termArrays[i];
                        List <SpanQuery> disjuncts = disjunctLists[positions[i]];
                        if (disjuncts == null)
                        {
                            disjuncts = (disjunctLists[positions[i]] = new List <SpanQuery>(termArray.Length));
                            ++distinctPositions;
                        }
                        foreach (var term in termArray)
                        {
                            disjuncts.Add(new SpanTermQuery(term));
                        }
                    }

                    int         positionGaps = 0;
                    int         position     = 0;
                    SpanQuery[] clauses      = new SpanQuery[distinctPositions];
                    foreach (var disjuncts in disjunctLists)
                    {
                        if (disjuncts != null)
                        {
                            clauses[position++] = new SpanOrQuery(disjuncts.ToArray());
                        }
                        else
                        {
                            ++positionGaps;
                        }
                    }

                    int  slop    = mpq.Slop;
                    bool inorder = (slop == 0);

                    SpanNearQuery sp = new SpanNearQuery(clauses, slop + positionGaps, inorder);
                    sp.Boost = query.Boost;
                    ExtractWeightedSpanTerms(terms, sp);
                }
            }
            else
            {
                Query origQuery = query;
                if (query is MultiTermQuery)
                {
                    if (!expandMultiTermQuery)
                    {
                        return;
                    }
                    MultiTermQuery copy = (MultiTermQuery)query.Clone();
                    copy.MultiTermRewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
                    origQuery = copy;
                }
                IndexReader reader    = GetLeafContext().Reader;
                Query       rewritten = origQuery.Rewrite(reader);
                if (rewritten != origQuery)
                {
                    // only rewrite once and then flatten again - the rewritten query could have a speacial treatment
                    // if this method is overwritten in a subclass or above in the next recursion
                    Extract(rewritten, terms);
                }
            }
            ExtractUnknownQuery(query, terms);
        }
예제 #25
0
 internal void Flatten(Query sourceQuery, IndexReader reader, ICollection <Query> flatQueries)
 {
     if (sourceQuery is BooleanQuery)
     {
         BooleanQuery bq = (BooleanQuery)sourceQuery;
         foreach (BooleanClause clause in bq)
         {
             if (!clause.IsProhibited)
             {
                 Flatten(ApplyParentBoost(clause.Query, bq), reader, flatQueries);
             }
         }
     }
     else if (sourceQuery is DisjunctionMaxQuery)
     {
         DisjunctionMaxQuery dmq = (DisjunctionMaxQuery)sourceQuery;
         foreach (Query query in dmq)
         {
             Flatten(ApplyParentBoost(query, dmq), reader, flatQueries);
         }
     }
     else if (sourceQuery is TermQuery)
     {
         if (!flatQueries.Contains(sourceQuery))
         {
             flatQueries.Add(sourceQuery);
         }
     }
     else if (sourceQuery is PhraseQuery)
     {
         if (!flatQueries.Contains(sourceQuery)) // LUCENENET - set semantics, but this is a list. The original logic was already correct.
         {
             PhraseQuery pq = (PhraseQuery)sourceQuery;
             if (pq.GetTerms().Length > 1)
             {
                 flatQueries.Add(pq);
             }
             else if (pq.GetTerms().Length == 1)
             {
                 Query flat = new TermQuery(pq.GetTerms()[0]);
                 flat.Boost = pq.Boost;
                 flatQueries.Add(flat);
             }
         }
     }
     else if (sourceQuery is ConstantScoreQuery)
     {
         Query q = ((ConstantScoreQuery)sourceQuery).Query;
         if (q != null)
         {
             Flatten(ApplyParentBoost(q, sourceQuery), reader, flatQueries);
         }
     }
     else if (sourceQuery is FilteredQuery)
     {
         Query q = ((FilteredQuery)sourceQuery).Query;
         if (q != null)
         {
             Flatten(ApplyParentBoost(q, sourceQuery), reader, flatQueries);
         }
     }
     else if (reader != null)
     {
         Query query = sourceQuery;
         if (sourceQuery is MultiTermQuery)
         {
             MultiTermQuery copy = (MultiTermQuery)sourceQuery.Clone();
             copy.MultiTermRewriteMethod = new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(MAX_MTQ_TERMS);
             query = copy;
         }
         Query rewritten = query.Rewrite(reader);
         if (rewritten != query)
         {
             // only rewrite once and then flatten again - the rewritten query could have a speacial treatment
             // if this method is overwritten in a subclass.
             Flatten(rewritten, reader, flatQueries);
         }
         // if the query is already rewritten we discard it
     }
     // else discard queries
 }