~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/QueryTermExtractor.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.search.highlight;
2
 
/**
3
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
4
 
 * contributor license agreements.  See the NOTICE file distributed with
5
 
 * this work for additional information regarding copyright ownership.
6
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
7
 
 * (the "License"); you may not use this file except in compliance with
8
 
 * the License.  You may obtain a copy of the License at
9
 
 *
10
 
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 
 *
12
 
 * Unless required by applicable law or agreed to in writing, software
13
 
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 
 * See the License for the specific language governing permissions and
16
 
 * limitations under the License.
17
 
 */
18
 
 
19
 
import java.io.IOException;
20
 
import java.util.HashSet;
21
 
import java.util.Iterator;
22
 
 
23
 
import org.apache.lucene.index.IndexReader;
24
 
import org.apache.lucene.index.Term;
25
 
import org.apache.lucene.search.BooleanClause;
26
 
import org.apache.lucene.search.BooleanQuery;
27
 
import org.apache.lucene.search.FilteredQuery;
28
 
import org.apache.lucene.search.Query;
29
 
import org.apache.lucene.util.StringHelper;
30
 
 
31
 
/**
32
 
 * Utility class used to extract the terms used in a query, plus any weights.
33
 
 * This class will not find terms for MultiTermQuery, TermRangeQuery and PrefixQuery classes
34
 
 * so the caller must pass a rewritten query (see Query.rewrite) to obtain a list of 
35
 
 * expanded terms. 
36
 
 * 
37
 
 */
38
 
public final class QueryTermExtractor
39
 
{
40
 
 
41
 
        /**
42
 
         * Extracts all terms texts of a given Query into an array of WeightedTerms
43
 
         *
44
 
         * @param query      Query to extract term texts from
45
 
         * @return an array of the terms used in a query, plus their weights.
46
 
         */
47
 
        public static final WeightedTerm[] getTerms(Query query) 
48
 
        {
49
 
                return getTerms(query,false);
50
 
        }
51
 
 
52
 
        /**
53
 
         * Extracts all terms texts of a given Query into an array of WeightedTerms
54
 
         *
55
 
         * @param query      Query to extract term texts from
56
 
         * @param reader used to compute IDF which can be used to a) score selected fragments better 
57
 
         * b) use graded highlights eg changing intensity of font color
58
 
         * @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based
59
 
         * @return an array of the terms used in a query, plus their weights.
60
 
         */
61
 
        public static final WeightedTerm[] getIdfWeightedTerms(Query query, IndexReader reader, String fieldName) 
62
 
        {
63
 
            WeightedTerm[] terms=getTerms(query,false, fieldName);
64
 
            int totalNumDocs=reader.numDocs();
65
 
            for (int i = 0; i < terms.length; i++)
66
 
        {
67
 
                try
68
 
            {
69
 
                int docFreq=reader.docFreq(new Term(fieldName,terms[i].term));
70
 
                // docFreq counts deletes
71
 
                if(totalNumDocs < docFreq) {
72
 
                  docFreq = totalNumDocs;
73
 
                }
74
 
                //IDF algorithm taken from DefaultSimilarity class
75
 
                float idf=(float)(Math.log((float)totalNumDocs/(double)(docFreq+1)) + 1.0);
76
 
                terms[i].weight*=idf;
77
 
            } 
78
 
                catch (IOException e)
79
 
            {
80
 
                    //ignore 
81
 
            }
82
 
        }
83
 
                return terms;
84
 
        }
85
 
 
86
 
        /**
87
 
         * Extracts all terms texts of a given Query into an array of WeightedTerms
88
 
         *
89
 
         * @param query      Query to extract term texts from
90
 
         * @param prohibited <code>true</code> to extract "prohibited" terms, too
91
 
         * @param fieldName  The fieldName used to filter query terms
92
 
   * @return an array of the terms used in a query, plus their weights.
93
 
   */
94
 
        public static final WeightedTerm[] getTerms(Query query, boolean prohibited, String fieldName) 
95
 
        {
96
 
                HashSet<WeightedTerm> terms=new HashSet<WeightedTerm>();
97
 
                if(fieldName!=null)
98
 
                {
99
 
                    fieldName= StringHelper.intern(fieldName);
100
 
                }
101
 
                getTerms(query,terms,prohibited,fieldName);
102
 
                return terms.toArray(new WeightedTerm[0]);
103
 
        }
104
 
        
105
 
        /**
106
 
         * Extracts all terms texts of a given Query into an array of WeightedTerms
107
 
         *
108
 
         * @param query      Query to extract term texts from
109
 
         * @param prohibited <code>true</code> to extract "prohibited" terms, too
110
 
   * @return an array of the terms used in a query, plus their weights.
111
 
   */
112
 
        public static final WeightedTerm[] getTerms(Query query, boolean prohibited) 
113
 
        {
114
 
            return getTerms(query,prohibited,null);
115
 
        }       
116
 
 
117
 
        //fieldname MUST be interned prior to this call
118
 
        private static final void getTerms(Query query, HashSet<WeightedTerm> terms,boolean prohibited, String fieldName) 
119
 
        {
120
 
        try
121
 
        {
122
 
                if (query instanceof BooleanQuery)
123
 
                        getTermsFromBooleanQuery((BooleanQuery) query, terms, prohibited, fieldName);
124
 
                else
125
 
                        if(query instanceof FilteredQuery)
126
 
                                getTermsFromFilteredQuery((FilteredQuery)query, terms,prohibited, fieldName);
127
 
                        else
128
 
                {
129
 
                        HashSet<Term> nonWeightedTerms=new HashSet<Term>();
130
 
                        query.extractTerms(nonWeightedTerms);
131
 
                        for (Iterator<Term> iter = nonWeightedTerms.iterator(); iter.hasNext();)
132
 
                                {
133
 
                                        Term term = iter.next();
134
 
                                    if((fieldName==null)||(term.field()==fieldName))
135
 
                                        {
136
 
                                                terms.add(new WeightedTerm(query.getBoost(),term.text()));
137
 
                                        }
138
 
                                }
139
 
                }
140
 
              }
141
 
              catch(UnsupportedOperationException ignore)
142
 
              {
143
 
                  //this is non-fatal for our purposes
144
 
          }                                                             
145
 
        }
146
 
 
147
 
        /**
148
 
         * extractTerms is currently the only query-independent means of introspecting queries but it only reveals
149
 
         * a list of terms for that query - not the boosts each individual term in that query may or may not have.
150
 
         * "Container" queries such as BooleanQuery should be unwrapped to get at the boost info held
151
 
         * in each child element. 
152
 
         * Some discussion around this topic here:
153
 
         * http://www.gossamer-threads.com/lists/lucene/java-dev/34208?search_string=introspection;#34208
154
 
         * Unfortunately there seemed to be limited interest in requiring all Query objects to implement
155
 
         * something common which would allow access to child queries so what follows here are query-specific
156
 
         * implementations for accessing embedded query elements. 
157
 
         */
158
 
        private static final void getTermsFromBooleanQuery(BooleanQuery query, HashSet<WeightedTerm> terms, boolean prohibited, String fieldName)
159
 
        {
160
 
                BooleanClause[] queryClauses = query.getClauses();
161
 
                for (int i = 0; i < queryClauses.length; i++)
162
 
                {
163
 
                        if (prohibited || queryClauses[i].getOccur()!=BooleanClause.Occur.MUST_NOT)
164
 
                                getTerms(queryClauses[i].getQuery(), terms, prohibited, fieldName);
165
 
                }
166
 
        }       
167
 
        private static void getTermsFromFilteredQuery(FilteredQuery query, HashSet<WeightedTerm> terms, boolean prohibited, String fieldName)
168
 
        {
169
 
                getTerms(query.getQuery(),terms,prohibited,fieldName);          
170
 
        }
171
 
        
172
 
}