如何在QueryParser中合并多个字段?

时间:2022-07-16 03:07:44
Dim qp1 As New QueryParser("filename", New StandardAnalyzer())
Dim qp2 As New QueryParser("filetext", New StandardAnalyzer())
.
.

I am using the 'Lucene.Net' library and have the following question.

我正在使用'Lucene.Net'库并提出以下问题。

Instead of creating two separate QueryParser objects and using them to obtain two Hits objects, is it possible perform a search on both fields using a single QueryParser object, so that I have only one Hits object which gives me the overall score of each Document?

不是创建两个单独的QueryParser对象并使用它们来获取两个Hits对象,而是可以使用单个QueryParser对象在两个字段上执行搜索,这样我只有一个Hits对象,它给出了每个Document的总分数?

4 个解决方案

#1


There are 3 ways to do this.

有3种方法可以做到这一点。

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:

第一种方法是手动构造查询,这就是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);

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.

第二种方法是使用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>"));

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

最后的方法是使用QueryParser的特殊语法,请参见此处。

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

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

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

#2


Just build a query string with each term:

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

"filename:searchText OR filetext:searchText"

It doesn't matter what you pass as the initial field in QueryParser's constructor. Just make sure you call .Parse() on your query string to get a Query object back to execute.

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

If you want to use an "and" search:

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

"+filename:searchText +filetext:searchText"

#3


** you can also use MultiFieldQueryParser to search in all available fields.**

**您还可以使用MultiFieldQueryParser搜索所有可用字段。**

E.g

Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29, 
indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)

here is complete an example.

这是一个完整的例子。

//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

hope that help

希望有所帮助

#4


for each field create a query from the above queryparsers, then add the query to a booleanquery stating that it "must" occur.

为每个字段创建一个来自上述查询器的查询,然后将查询添加到booleanquery,表明它“必须”发生。

Alternatively, check out the MultiFieldQueryParser, which is a simplified way of doing it.

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

#1


There are 3 ways to do this.

有3种方法可以做到这一点。

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:

第一种方法是手动构造查询,这就是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);

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.

第二种方法是使用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>"));

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

最后的方法是使用QueryParser的特殊语法,请参见此处。

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

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

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

#2


Just build a query string with each term:

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

"filename:searchText OR filetext:searchText"

It doesn't matter what you pass as the initial field in QueryParser's constructor. Just make sure you call .Parse() on your query string to get a Query object back to execute.

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

If you want to use an "and" search:

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

"+filename:searchText +filetext:searchText"

#3


** you can also use MultiFieldQueryParser to search in all available fields.**

**您还可以使用MultiFieldQueryParser搜索所有可用字段。**

E.g

Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29, 
indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)

here is complete an example.

这是一个完整的例子。

//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

hope that help

希望有所帮助

#4


for each field create a query from the above queryparsers, then add the query to a booleanquery stating that it "must" occur.

为每个字段创建一个来自上述查询器的查询,然后将查询添加到booleanquery,表明它“必须”发生。

Alternatively, check out the MultiFieldQueryParser, which is a simplified way of doing it.

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