34
Dim qp1 As New QueryParser("filename", New StandardAnalyzer())
Dim qp2 As New QueryParser("filetext", New StandardAnalyzer())
.
.

我正在使用“Lucene.Net”库并有以下问题。

与其创建两个单独的QueryParser对象并使用它们来获得两个 Hits 对象,是否可以使用单个QueryParser对象在两个字段上执行搜索,以便我只有一个 Hits 对象可以为我提供每个文档的总分?

4

4 回答 4

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));

您的另一种选择是在索引名为文件名和文本的内容时创建新字段,您可以将文件名和文件文本的内容放入其中然后您只需搜索一个字段。

于 2010-01-10T11:54:34.840 回答
4

只需为每个术语构建一个查询字符串:

"filename:searchText OR filetext:searchText"

在 QueryParser 的构造函数中作为初始字段传递的内容并不重要。只需确保在查询字符串上调用 .Parse() 即可让 Query 对象重新执行。

如果您想使用“和”搜索:

"+filename:searchText +filetext:searchText"
于 2009-02-10T14:03:09.080 回答
2

** 您也可以使用MultiFieldQueryParser它在所有可用字段中进行搜索。**

例如

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

希望有帮助

于 2012-06-06T07:51:19.917 回答
1

对于每个字段,从上述查询解析器创建一个查询,然后将查询添加到布尔查询,说明它“必须”发生。

或者,查看 MultiFieldQueryParser,这是一种简化的方法。

于 2009-01-23T10:36:01.503 回答