Reputation: 2998
I'm trying to nest one BooleanQuery inside of another.
The inner BooleanQuery is created with the following code and added to topBQuery.
BooleanQuery topBQuery = new BooleanQuery();
// add a numeric range query on loan amount.
if( row.getLoan_amt() > 0 ){
BooleanQuery loanBQuery = new BooleanQuery();
Double loanMin = 0.0;
Double loanMax = 0.0;
Double loanAmt = row.getLoan_amt();
// Range should be within +- 5% of loan amount.
loanMin = loanAmt - (loanAmt * .05);
loanMax = loanAmt + (loanAmt * .05);
loanBQuery.add(NumericRangeQuery.newDoubleRange(TitleRecordColumns.SR_LOAN_VAL_1.toString(), loanMin, loanMax, true, true), BooleanClause.Occur.SHOULD);
loanBQuery.add(NumericRangeQuery.newDoubleRange(TitleRecordColumns.SR_LOAN_VAL_2.toString(), loanMin, loanMax, true, true), BooleanClause.Occur.SHOULD);
loanBQuery.add(NumericRangeQuery.newDoubleRange(TitleRecordColumns.SR_LOAN_VAL_3.toString(), loanMin, loanMax, true, true), BooleanClause.Occur.SHOULD);
topBQuery.add(loanBQuery, BooleanClause.Occur.MUST);
}
Another field is added to topBQuery with the following:
if( !row.getPropertykey_tx().isEmpty() ){
//TitleRecordColumns is an enum
topBQuery.add(new TermQuery(new Term(TitleRecordColumns.SA_SITE_ADDR.toString(), row.getPropertykey_tx())), BooleanClause.Occur.SHOULD);
}
I only want documents that match the ranges I've created in any of the SR_LOAN_VAL fields. A record should also match the provided address. Am I creating the BooleanQuery properly?
Is there also a better way to do this kind of search?
I'm using Lucene 4.7. I've looked at my index with Luke and I am confident that I've indexed the fields properly. Thank you!
Edit:
This is the code I am using to generate the "final query" that I use to search the index with. Most examples I've seen do something like this. Is this correct?
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);
Query finalQuery = new QueryParser(Version.LUCENE_47, TitleRecordColumns.SA_SITE_ADDR.toString(), analyzer).parse(topBQuery.toString());
IndexSearcher searcher = new IndexSearcher(reader);
TopDocs results = searcher.search(finalQuery, 5);
Upvotes: 0
Views: 342
Reputation: 33341
Looks reasonable to me.
When you say that A record "should" also match the address, it is not clear what you mean though. If you mean that all results Must match the address, then you should change the Occur argument when adding that subquery to BooleanClause.Occur.MUST
. If you mean that it is preferred to have a match on that field, and you want to see those documents at the top, but anything matching the numeric range queries is an acceptable result, then your current query is correct.
Upvotes: 1