01: package org.apache.lucene.search;
02:
03: /**
04: * Licensed to the Apache Software Foundation (ASF) under one or more
05: * contributor license agreements. See the NOTICE file distributed with
06: * this work for additional information regarding copyright ownership.
07: * The ASF licenses this file to You under the Apache License, Version 2.0
08: * (the "License"); you may not use this file except in compliance with
09: * the License. You may obtain a copy of the License at
10: *
11: * http://www.apache.org/licenses/LICENSE-2.0
12: *
13: * Unless required by applicable law or agreed to in writing, software
14: * distributed under the License is distributed on an "AS IS" BASIS,
15: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16: * See the License for the specific language governing permissions and
17: * limitations under the License.
18: */
19:
20: import java.io.IOException;
21:
22: import org.apache.lucene.index.IndexReader;
23: import org.apache.lucene.search.BooleanQuery;
24: import org.apache.lucene.search.DefaultSimilarity;
25: import org.apache.lucene.search.Query;
26: import org.apache.lucene.search.Searcher;
27: import org.apache.lucene.search.Similarity;
28:
29: /**
30: * The BoostingQuery class can be used to effectively demote results that match a given query.
31: * Unlike the "NOT" clause, this still selects documents that contain undesirable terms,
32: * but reduces their overall score:
33: *
34: * Query balancedQuery = new BoostingQuery(positiveQuery, negativeQuery, 0.01f);
35: * In this scenario the positiveQuery contains the mandatory, desirable criteria which is used to
36: * select all matching documents, and the negativeQuery contains the undesirable elements which
37: * are simply used to lessen the scores. Documents that match the negativeQuery have their score
38: * multiplied by the supplied "boost" parameter, so this should be less than 1 to achieve a
39: * demoting effect
40: *
41: * This code was originally made available here: [WWW] http://marc.theaimsgroup.com/?l=lucene-user&m=108058407130459&w=2
42: * and is documented here: http://wiki.apache.org/lucene-java/CommunityContributions
43: */
44: public class BoostingQuery extends Query {
45: private float boost; // the amount to boost by
46: private Query match; // query to match
47: private Query context; // boost when matches too
48:
49: public BoostingQuery(Query match, Query context, float boost) {
50: this .match = match;
51: this .context = (Query) context.clone(); // clone before boost
52: this .boost = boost;
53:
54: this .context.setBoost(0.0f); // ignore context-only matches
55: }
56:
57: public Query rewrite(IndexReader reader) throws IOException {
58: BooleanQuery result = new BooleanQuery() {
59:
60: public Similarity getSimilarity(Searcher searcher) {
61: return new DefaultSimilarity() {
62:
63: public float coord(int overlap, int max) {
64: switch (overlap) {
65:
66: case 1: // matched only one clause
67: return 1.0f; // use the score as-is
68:
69: case 2: // matched both clauses
70: return boost; // multiply by boost
71:
72: default:
73: return 0.0f;
74:
75: }
76: }
77: };
78: }
79: };
80:
81: result.add(match, BooleanClause.Occur.MUST);
82: result.add(context, BooleanClause.Occur.SHOULD);
83:
84: return result;
85: }
86:
87: public String toString(String field) {
88: return match.toString(field) + "/" + context.toString(field);
89: }
90: }
|