Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
BoostingQuery.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using System.Collections.Generic;
20 using System.Linq;
21 using System.Text;
22 
23 using Lucene.Net.Index;
24 using Lucene.Net.Search;
25 
26 namespace Lucene.Net.Search
27 {
28  /// <summary>
29  /// The BoostingQuery class can be used to effectively demote results that match a given query.
30  /// Unlike the "NOT" clause, this still selects documents that contain undesirable terms,
31  /// but reduces their overall score:
32  /// <pre>
33  /// Query balancedQuery = new BoostingQuery(positiveQuery, negativeQuery, 0.01f);
34  /// </pre>
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:
42  /// <a href="http://marc.theaimsgroup.com/?l=lucene-user&amp;m=108058407130459&amp;w=2">mailing list</a>
43  /// and is documented here: <a href="http://wiki.apache.org/lucene-java/CommunityContributions">Documentation</a>
44  /// </summary>
45  public class BoostingQuery : Query
46  {
47  private float boost; // the amount to boost by
48  private Query match; // query to match
49  private Query context; // boost when matches too
50 
51  public BoostingQuery(Query match, Query context, float boost)
52  {
53  this.match = match;
54  this.context = (Query)context.Clone(); // clone before boost
55  this.boost = boost;
56 
57  this.context.Boost = 0.0f; // ignore context-only matches
58  }
59 
60  public override Query Rewrite(IndexReader reader)
61  {
62  BooleanQuery result = new AnonymousBooleanQuery(boost);
63 
64  result.Add(match, Occur.MUST);
65  result.Add(context, Occur.SHOULD);
66 
67  return result;
68  }
69 
70  class AnonymousBooleanQuery : BooleanQuery
71  {
72  float boost;
73  public AnonymousBooleanQuery(float boost)
74  {
75  this.boost = boost;
76  }
77 
78  public override Similarity GetSimilarity(Searcher searcher)
79  {
80  return new AnonymousDefaultSimilarity(boost);
81  }
82  }
83 
84  class AnonymousDefaultSimilarity : DefaultSimilarity
85  {
86  float boost ;
87  public AnonymousDefaultSimilarity(float boost)
88  {
89  this.boost = boost;
90  }
91 
92  public override float Coord(int overlap, int max)
93  {
94  switch (overlap)
95  {
96 
97  case 1: // matched only one clause
98  return 1.0f; // use the score as-is
99 
100  case 2: // matched both clauses
101  return boost; // multiply by boost
102 
103  default:
104  return 0.0f;
105 
106  }
107  }
108  }
109 
110  public override int GetHashCode()
111  {
112  int prime = 31;
113  int result = 1;
114  result = prime * result + BitConverter.ToInt32(BitConverter.GetBytes(boost),0);
115  result = prime * result + ((context == null) ? 0 : context.GetHashCode());
116  result = prime * result + ((match == null) ? 0 : match.GetHashCode());
117  return result;
118  }
119 
120  public override bool Equals(Object obj)
121  {
122  if (this == obj)
123  return true;
124  if (obj == null)
125  return false;
126  if (this.GetType() != obj.GetType())
127  return false;
128  BoostingQuery other = (BoostingQuery)obj;
129  if (BitConverter.ToInt32(BitConverter.GetBytes(boost),0) != BitConverter.ToInt32(BitConverter.GetBytes(other.boost),0) )
130  return false;
131  if (context == null)
132  {
133  if (other.context != null)
134  return false;
135  }
136  else if (!context.Equals(other.context))
137  return false;
138  if (match == null)
139  {
140  if (other.match != null)
141  return false;
142  }
143  else if (!match.Equals(other.match))
144  return false;
145  return true;
146  }
147 
148  public override String ToString(String field)
149  {
150  return match.ToString(field) + "/" + context.ToString(field);
151  }
152  }
153 }