Reputation: 1252
I am utilizing the Lucene.net version 3.0 API to create and search an index for my project. Each Document in my index has three Fields:
My requirements are this:
I want a hit if a search term matches the first part of a Document's value for TransactionId. For example, if I search for "ab" then Documents with TransactionId equal to "ab-1" or "ab-2" would be hits.
I only want hits when the full search term matches Agent and Lender. The search for "ab" would not return Documents where the value of Lender is "ab-1" or "ab-2".
So far, I have the following block of code:
var searcher = new IndexSearcher(FSDirectory.Open(path));
var parser = new MultiFieldQueryParser(Version.LUCENE_30,
new[] {"TransactionId", "Agent", "Lender"},
new StandardAnalyzer(Version.LUCENE_30));
var query = parser.Parse(queryText);
var hits = searcher.Search(query, 200);
If queryText
is "ab" then the value of query is {TransactionId:ab Agent:ab Lender:ab}
I know I am looking for it to be something like {TransactionId:ab* Agent:ab Lender:ab}
Is there any way to do this with the MultiFieldQueryParser
?
Upvotes: 0
Views: 834
Reputation: 5246
You could probably achieve that by subclassing the MultiFieldQueryParser
.
The following seems to works, maybe something you can build on. Note that parsing the BooleanQuery should be recursive as you could end up with nested queries eventually.
Disclaimer: this code isnt elegant and probably breaks very easily as is, its intended as a quick example
public class WildCardForFieldQueryParser : MultiFieldQueryParser
{
public WildCardForFieldQueryParser(Lucene.Net.Util.Version version,
string [] fields,
Analyzer analyzer,
HashSet<string> wildcardFields)
:base(version, fields, analyzer)
{
this._wildcardFields = wildcardFields;
}
public override Query Parse(string query)
{
// clause replacement should be recursive
Query q = base.Parse(query);
if (q is BooleanQuery)
{
foreach (var clause in q as BooleanQuery)
{
if (clause.Query is TermQuery && this._wildcardFields.Contains(((TermQuery)clause.Query).Term.Field))
{
clause.Query = new PrefixQuery(new Term(((TermQuery)clause.Query).Term.Field, ((TermQuery)clause.Query).Term.Text));
}
}
}
return q;
}
private HashSet<string> _wildcardFields;
}
Upvotes: 1