Dim qp1 As New QueryParser("filename", New StandardAnalyzer())
Dim qp2 As New QueryParser("filetext", New StandardAnalyzer())
.
.
我正在使用'Lucene.Net'库并提出以下问题。
不是创建两个单独的QueryParser
对象并使用它们来获取两个Hits对象,而是可以使用单个QueryParser
对象在两个字段上执行搜索,这样我只有一个Hits对象这给了我每份文件的总分?
答案 0 :(得分:77)
有3种方法可以做到这一点。
第一种方法是手动构建查询,这是QueryParser
在内部执行的操作。这是最强大的方法,这意味着如果您想要阻止访问QueryParser
的一些更奇特的功能,则不必解析用户输入:
IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);
BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("filename", "<text>"));
Query query2 = new TermQuery(new Term("filetext", "<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);
第二种方法是使用MultiFieldQueryParser
,其行为类似QueryParser
,允许访问它拥有的所有权力,但它会搜索多个字段。
IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(
new string[] {"filename", "filetext"},
analyzer);
Hits hits = searcher.Search(queryParser.parse("<text>"));
最后一种方法是使用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 = "filename:" + text + " OR filetext:" + text;
Hits hits = searcher.Search(queryParser.parse(special));
您的另一个选择是在索引名为filenameandtext的内容时创建新字段,您可以在其中放置 filename和filetext的内容,然后您只需要搜索一个字段。
答案 1 :(得分:4)
只需使用每个术语构建一个查询字符串:
"filename:searchText OR filetext:searchText"
作为QueryParser构造函数中的初始字段传递的内容并不重要。只需确保在查询字符串上调用.Parse()以使Query对象返回执行。
如果您想使用“和”搜索:
"+filename:searchText +filetext:searchText"
答案 2 :(得分:2)
**您也可以使用MultiFieldQueryParser
搜索所有可用字段。**
E.g
Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29,
indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)
这里是一个完整的例子。
//get index directory
Dim directory As Directory = FSDirectory.Open(New DirectoryInfo(HostingEnvironment.MapPath(VirtualIndexPath)))
//get analyzer
Dim analyzer As Analyzer = New StandardAnalyzer(Version.LUCENE_29)
//get index reader and searcher
Dim indexReader__1 As IndexReader = IndexReader.Open(directory, True)
Dim indexSearch As Searcher = New IndexSearcher(indexReader__1)
//add all possible fileds in multifieldqueryparser using indexreader getFieldNames method
Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29, indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)
Dim query = queryParser.Parse(Criteria)
Dim resultDocs As TopDocs = Nothing
//perform search
resultDocs = indexSearch.Search(query, indexReader__1.MaxDoc())
Dim hits = resultDocs.scoreDocs
希望有帮助
答案 3 :(得分:1)
为每个字段创建一个来自上述查询器的查询,然后将查询添加到一个booleanquery,表明它“必须”发生。
或者,查看MultiFieldQueryParser,这是一种简化的方法。