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
FieldMaskingSpanQuery.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 Lucene.Net.Index;
20 using IndexReader = Lucene.Net.Index.IndexReader;
21 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
22 using Query = Lucene.Net.Search.Query;
23 using Searcher = Lucene.Net.Search.Searcher;
24 using Similarity = Lucene.Net.Search.Similarity;
25 using Weight = Lucene.Net.Search.Weight;
26 
27 namespace Lucene.Net.Search.Spans
28 {
29 
30  /// <summary> <p/>Wrapper to allow <see cref="SpanQuery" /> objects participate in composite
31  /// single-field SpanQueries by 'lying' about their search field. That is,
32  /// the masked SpanQuery will function as normal,
33  /// but <see cref="SpanQuery.Field" /> simply hands back the value supplied
34  /// in this class's constructor.<p/>
35  ///
36  /// <p/>This can be used to support Queries like <see cref="SpanNearQuery" /> or
37  /// <see cref="SpanOrQuery" /> across different fields, which is not ordinarily
38  /// permitted.<p/>
39  ///
40  /// <p/>This can be useful for denormalized relational data: for example, when
41  /// indexing a document with conceptually many 'children': <p/>
42  ///
43  /// <pre>
44  /// teacherid: 1
45  /// studentfirstname: james
46  /// studentsurname: jones
47  ///
48  /// teacherid: 2
49  /// studenfirstname: james
50  /// studentsurname: smith
51  /// studentfirstname: sally
52  /// studentsurname: jones
53  /// </pre>
54  ///
55  /// <p/>a SpanNearQuery with a slop of 0 can be applied across two
56  /// <see cref="SpanTermQuery" /> objects as follows:
57  /// <code>
58  /// SpanQuery q1 = new SpanTermQuery(new Term("studentfirstname", "james"));
59  /// SpanQuery q2 = new SpanTermQuery(new Term("studentsurname", "jones"));
60  /// SpanQuery q2m new FieldMaskingSpanQuery(q2, "studentfirstname");
61  /// Query q = new SpanNearQuery(new SpanQuery[]{q1, q2m}, -1, false);
62  /// </code>
63  /// to search for 'studentfirstname:james studentsurname:jones' and find
64  /// teacherid 1 without matching teacherid 2 (which has a 'james' in position 0
65  /// and 'jones' in position 1). <p/>
66  ///
67  /// <p/>Note: as <see cref="Field" /> returns the masked field, scoring will be
68  /// done using the norms of the field name supplied. This may lead to unexpected
69  /// scoring behaviour.<p/>
70  /// </summary>
71  [Serializable]
73  {
74  private SpanQuery maskedQuery;
75  private System.String field;
76 
77  public FieldMaskingSpanQuery(SpanQuery maskedQuery, System.String maskedField)
78  {
79  this.maskedQuery = maskedQuery;
80  this.field = maskedField;
81  }
82 
83  public override string Field
84  {
85  get { return field; }
86  }
87 
88  public virtual SpanQuery MaskedQuery
89  {
90  get { return maskedQuery; }
91  }
92 
93  // :NOTE: getBoost and setBoost are not proxied to the maskedQuery
94  // ...this is done to be more consistent with thigns like SpanFirstQuery
95 
96  public override Spans GetSpans(IndexReader reader)
97  {
98  return maskedQuery.GetSpans(reader);
99  }
100 
101  public override void ExtractTerms(System.Collections.Generic.ISet<Term> terms)
102  {
103  maskedQuery.ExtractTerms(terms);
104  }
105 
106  public override Weight CreateWeight(Searcher searcher)
107  {
108  return maskedQuery.CreateWeight(searcher);
109  }
110 
111  public override Similarity GetSimilarity(Searcher searcher)
112  {
113  return maskedQuery.GetSimilarity(searcher);
114  }
115 
116  public override Query Rewrite(IndexReader reader)
117  {
118  FieldMaskingSpanQuery clone = null;
119 
120  SpanQuery rewritten = (SpanQuery) maskedQuery.Rewrite(reader);
121  if (rewritten != maskedQuery)
122  {
123  clone = (FieldMaskingSpanQuery) this.Clone();
124  clone.maskedQuery = rewritten;
125  }
126 
127  if (clone != null)
128  {
129  return clone;
130  }
131  else
132  {
133  return this;
134  }
135  }
136 
137  public override System.String ToString(System.String field)
138  {
139  System.Text.StringBuilder buffer = new System.Text.StringBuilder();
140  buffer.Append("mask(");
141  buffer.Append(maskedQuery.ToString(field));
142  buffer.Append(")");
143  buffer.Append(ToStringUtils.Boost(Boost));
144  buffer.Append(" as ");
145  buffer.Append(this.field);
146  return buffer.ToString();
147  }
148 
149  public override bool Equals(System.Object o)
150  {
151  if (!(o is FieldMaskingSpanQuery))
152  return false;
153  FieldMaskingSpanQuery other = (FieldMaskingSpanQuery) o;
154  return (this.Field.Equals(other.Field) && (this.Boost == other.Boost) && this.MaskedQuery.Equals(other.MaskedQuery));
155  }
156 
157  public override int GetHashCode()
158  {
159  return MaskedQuery.GetHashCode() ^ Field.GetHashCode() ^ System.Convert.ToInt32(Boost);
160  }
161  }
162 }