In Lucene, we can use TermQuery to search a text with a field. I am wondering how to search a keyword across a bunch of fields or all the searchable fields?
3 Answers
Another approach, which doesn't require to index anything more than what you already have, nor to combine different queries, is using the MultiFieldQueryParser
.
You can provide a list of fields where you want to search on and your query, that's all.
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(
Version.LUCENE_41,
new String[]{"title", "content", "description"},
new StandardAnalyzer(Version.LUCENE_41));
Query query = queryParser.parse("here goes your query");
This is how I would do it with the original lucene library written in Java. I'm not sure whether the MultiFieldQueryParser
is available in lucene.net too.
-
MultiFieldQueryParser is an elegant approach.. :) – phanin Mar 02 '13 at 16:04
-
Thanks, your answer is not bad either ;) +1 – javanna Mar 02 '13 at 16:14
-
It is, at least in 4.8 (the latest as of this Comment), in Lucene.Net - it's in the Lucene.Net.QueryParser Project, under the Classic folder. – Chris Moschini Nov 19 '18 at 15:25
Two approaches
1) Index-time approach: Use a catch-all field. This is nothing but appending all the text from all the fields (total text from your input doc) and place that resulting huge text in a single field. You've to add an additional field while indexing to act as a catch-all field.
2) Search-time approach: Use a BooleanQuery to combine multiple queries, for example TermQuery instances. Those multiple queries can be formed to cover all the target fields.
Example check at the end of the article.
Use approach 2 if you know the target-field list at runtime. Otherwise, you've got to use the 1st approach.

- 5,327
- 5
- 32
- 50
-
1Thanks for good big picture explanation. The first approach is what I use when storing different types of products in same index, for example Printers versus Monitors, where different fields exist for each doc but I want to use "full-text" search with a simple search string and bring back all products that match. – nothingisnecessary Feb 10 '17 at 02:10
Another easy approach to search across all fields using "MultifieldQueryParser" is use IndexReader.FieldOption.ALL in your query.
Here is example in c#.
Directory directory = FSDirectory.Open(new DirectoryInfo(HostingEnvironment.MapPath(VirtualIndexPath)));
//get analyzer
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
//get index reader and searcher
IndexReader indexReader__1 = IndexReader.Open(directory, true);
Searcher indexSearch = new IndexSearcher(indexReader__1);
//add all possible fileds in multifieldqueryparser using indexreader getFieldNames method
var queryParser = new MultiFieldQueryParser(Version.LUCENE_29, indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer);
var query = queryParser.Parse(Criteria);
TopDocs resultDocs = null;
//perform search
resultDocs = indexSearch.Search(query, indexReader__1.MaxDoc());
var hits = resultDocs.scoreDocs;
click here to check out my pervious answer to same quesiton in vb.net

- 5,165
- 38
- 50

- 766
- 7
- 19
-
I don't see the point of using duck typing here (i.e. `dynamic` keyword). Maybe you wanted to use type interence with `var`? – Matías Fidemraizer Nov 04 '16 at 10:13