How to specify two Fields in Lucene QueryParser?

JavaParsingLucenelucene.netInformation Retrieval

Java Problem Overview


I read https://stackoverflow.com/questions/468405/lucene-net-how-to-incorporate-multiple-fields-in-queryparser but i didn't get it.

At the moment i have a very strange construction like:

parser = New QueryParser("bodytext", analyzer)
parser2 = New QueryParser("title", analyzer)
query = parser.Parse(strSuchbegriff)
query2 = parser.Parse(strSuchbegriff)

What can i do for something like:

parser = New QuerParser ("bodytext" , "title",analyzer)
query =parser.Parse(strSuchbegriff) 

so the Parser looks for the searching word in the field "bodytext" an in the field "title".

Java Solutions


Solution 1 - Java

There are 3 ways to do this.

The first way is to construct a query manually, this is what QueryParser is doing internally. This is the most powerful way to do it, and means that you don't have to parse the user input if you want to prevent access to some of the more exotic features of QueryParser:

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);

BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("bodytext", "<text>"));
Query query2 = new TermQuery(new Term("title", "<text>"));
booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
booleanQuery.add(query2, BooleanClause.Occur.SHOULD);
// Use BooleanClause.Occur.MUST instead of BooleanClause.Occur.SHOULD
// for AND queries
Hits hits = searcher.Search(booleanQuery);

The second way is to use MultiFieldQueryParser, this behaves like QueryParser, allowing access to all the power that it has, except that it will search over multiple fields.

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);

Analyzer analyzer = new StandardAnalyzer();
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(
                                        new string[] {"bodytext", "title"},
                                        analyzer);

Hits hits = searcher.Search(queryParser.parse("<text>"));

The final way is to use the special syntax of QueryParser see here.

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);    

Analyzer analyzer = new StandardAnalyzer();
QueryParser queryParser = new QueryParser("<default field>", analyzer);
// <default field> is the field that QueryParser will search if you don't 
// prefix it with a field.
string special = "bodytext:" + text + " OR title:" + text;

Hits hits = searcher.Search(queryParser.parse(special));

Your other option is to create new field when you index your content called bodytextandtitle, into which you can place the contents of both bodytext and title, then you only have to search one field.

Solution 2 - Java

We can not use BooleanQuery booleanQuery = new BooleanQuery();

We have to use builder BooleanQuery.Builder finalQuery = new BooleanQuery.Builder(); then we can use finalQuery.build(); to get query

more generic way to do this is

private static TopDocs search(Map filters, IndexSearcher searcher) throws Exception {
StandardAnalyzer analyzer = new StandardAnalyzer();
BooleanQuery.Builder finalQuery = new BooleanQuery.Builder();

for(String attribute : filters.keySet()) {
	QueryParser queryParser = new QueryParser(attribute, analyzer);
	Query query = queryParser.parse(filters.get(attribute));
	finalQuery.add(query, Occur.MUST);
}

TopDocs hits = searcher.search(finalQuery.build(),10);
return hits;

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTyzakView Question on Stackoverflow
Solution 1 - JavaSam DoshiView Answer on Stackoverflow
Solution 2 - JavaNitish DhapodkarView Answer on Stackoverflow