Asp.net .NET Lucene:为什么获胜';BooleanQuery中的t MultiFieldQueryParser和WhitespaceAnalyzer查询产生正确的结果,如何修复?

Asp.net .NET Lucene:为什么获胜';BooleanQuery中的t MultiFieldQueryParser和WhitespaceAnalyzer查询产生正确的结果,如何修复?,asp.net,lucene,lucene.net,Asp.net,Lucene,Lucene.net,所以,我想构造一个简短的查询。我使用一个布尔查询来指定与索引匹配的文档的“type”字段必须是“Idea”,然后我有一个用户给出的搜索字符串,可能是一个或多个单词。我希望能够以编程方式限制客户端的结果,使其仅包含索引中字段“type”等于“index”的文档,但我也希望它们的搜索词能够将搜索短语中的任何单词与结果中的一个单词相匹配。我想下面的代码正好解释了我想要什么 WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer(); MultiFie

所以,我想构造一个简短的查询。我使用一个布尔查询来指定与索引匹配的文档的“type”字段必须是“Idea”,然后我有一个用户给出的搜索字符串,可能是一个或多个单词。我希望能够以编程方式限制客户端的结果,使其仅包含索引中字段“type”等于“index”的文档,但我也希望它们的搜索词能够将搜索短语中的任何单词与结果中的一个单词相匹配。我想下面的代码正好解释了我想要什么

WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer();

MultiFieldQueryParser parser = new MultiFieldQueryParser(
    Version.LUCENE_30, new string[] { "company", "description", 
    "name", "posterName"},
    analyzer);

parser.AllowLeadingWildcard = true;

Lucene.Net.Search.Query query = parser.Parse(searchParam); 

BooleanQuery bq = new BooleanQuery(); 

TermQuery tQuery = new TermQuery(new Lucene.Net.Index.Term("type", "Idea"));

bq.Add(tQuery, Lucene.Net.Search.Occur.MUST);

bq.Add(query, Lucene.Net.Search.Occur.MUST);
我为数据编制索引的方式在以下简短的相关代码中进行了描述:

Document doc = new Document();
doc.Add(new Field("type",
    "Idea",
    Field.Store.YES,
    Field.Index.ANALYZED));
doc.Add(new Field("company",
    (_idea.Company==null ?
      "Company Not Set for Idea" 
      : _idea.Company.Name),
    Field.Store.YES,
    Field.Index.ANALYZED));
doc.Add(new Field("description",
    _idea.Description,
    Field.Store.YES,
    Field.Index.ANALYZED));
doc.Add(new Field("name",
    _idea.Name,
    Field.Store.YES,Field.Index.ANALYZED));
if (_idea.Poster != null)
{
    doc.Add(new Field("posterName",
      _idea.Poster.FirstName + " " + _idea.Poster.LastName,
      Field.Store.YES, Field.Index.ANALYZED));
}
doc.Add(new Field("ID",
    _idea.ID.ToString(), Field.Store.YES,
    Field.Index.NOT_ANALYZED));
iWriter.AddDocument(doc);
我不明白的是,当我搜索我知道存在于索引中的给定单词时,它不会返回任何结果。只有当我使用通配符如“*”或其他东西搜索时,我才能得到任何结果。我的想法是,如果代码完全按照它对多字段QueryParser上的文档所说的那样执行,那么如果在文档中找到company、description、name等参数中的任何字段,它将返回匹配项。但事实并非如此。例如,在其中一个文档中,我知道我有一个名称字段“另一个想法”。当我搜索“另一个”/“另一个”/“想法”/ect时,它应该返回特定的文档。但它不。。。但是,它确实可以按类型正确过滤结果


我需要做些什么才能让这个简短的代码片段返回我想要的匹配项?

我找到了解决这个问题的方法,结果证明这是一个很简单的问题(取决于您对lucene和使用Visual Studio asp项目的了解程度,我并不太熟悉)。这是我的第一次

事实证明,您可以使用BooleanQuery对象将不同的查询添加到一起,并指定希望它们如何一起操作。然后,您可以将所有查询的最终总和传递给搜索者

事实证明,我并没有拆分对象并创建查询:我在下面附上了适用于我的示例解决方案:

    StandardAnalyzer analyzer =
        new StandardAnalyzer(Version.LUCENE_30);
    MultiFieldQueryParser mfqp = new MultiFieldQueryParser(
         Version.LUCENE_30, new string[] {"company", "description", 
         "name", "posterName"},
         analyzer);
    mfqp.DefaultOperator = MultiFieldQueryParser.OR_OPERATOR;
         mfqp.AllowLeadingWildcard = true;
         BooleanQuery innerExpr = new BooleanQuery();
         foreach (string s in searchParam.Split(new char[] {' '})) {
             innerExpr.Add(mfqp.Parse(s), Occur.SHOULD);
         }
   innerExpr.Add(new WildcardQuery(new Term("company", searchParam)), Occur.SHOULD);
   innerExpr.Add(new WildcardQuery(new Term("description", searchParam)), Occur.SHOULD);
   innerExpr.Add(new WildcardQuery(new Term("name", searchParam)), Occur.SHOULD);
   innerExpr.Add(new WildcardQuery(new Term("posterName", searchParam)), Occur.SHOULD);

   TermQuery tQuery = new TermQuery(new Term("type", "Idea"));

   //bq.Add(mfqp.Parse(searchParam), Lucene.Net.Search.Occur.MUST);
   TopDocs hits = sharedIndex.Search(innerExpr,
       new QueryWrapperFilter(tQuery), 1000, 
       new Sort(SortField.FIELD_DOC));

当我开始这项工作时,整个过程对我来说都不清楚。

我找到了解决这个问题的方法,结果证明这是一个很简单的问题(取决于您对lucene和使用Visual Studio asp项目的了解程度,我并不太熟悉)。这是我的第一次

事实证明,您可以使用BooleanQuery对象将不同的查询添加到一起,并指定希望它们如何一起操作。然后,您可以将所有查询的最终总和传递给搜索者

事实证明,我并没有拆分对象并创建查询:我在下面附上了适用于我的示例解决方案:

    StandardAnalyzer analyzer =
        new StandardAnalyzer(Version.LUCENE_30);
    MultiFieldQueryParser mfqp = new MultiFieldQueryParser(
         Version.LUCENE_30, new string[] {"company", "description", 
         "name", "posterName"},
         analyzer);
    mfqp.DefaultOperator = MultiFieldQueryParser.OR_OPERATOR;
         mfqp.AllowLeadingWildcard = true;
         BooleanQuery innerExpr = new BooleanQuery();
         foreach (string s in searchParam.Split(new char[] {' '})) {
             innerExpr.Add(mfqp.Parse(s), Occur.SHOULD);
         }
   innerExpr.Add(new WildcardQuery(new Term("company", searchParam)), Occur.SHOULD);
   innerExpr.Add(new WildcardQuery(new Term("description", searchParam)), Occur.SHOULD);
   innerExpr.Add(new WildcardQuery(new Term("name", searchParam)), Occur.SHOULD);
   innerExpr.Add(new WildcardQuery(new Term("posterName", searchParam)), Occur.SHOULD);

   TermQuery tQuery = new TermQuery(new Term("type", "Idea"));

   //bq.Add(mfqp.Parse(searchParam), Lucene.Net.Search.Occur.MUST);
   TopDocs hits = sharedIndex.Search(innerExpr,
       new QueryWrapperFilter(tQuery), 1000, 
       new Sort(SortField.FIELD_DOC));

当我开始讨论这个问题时,我并不清楚整个过程。

为了适应将来对索引的更改,您可以对该解决方案进行改进,即创建一个字符串数组变量来保存字段名,例如:

string[] allFields = new string[] {"company", "description", 
     "name", "posterName"};
这反过来将为您提供一个值,以便输入到解析器中:

MultiFieldQueryParser mfqp = new MultiFieldQueryParser(
     Version.LUCENE_30, allFields, analyzer);
以及通过字段进行迭代并使用一行添加通配符查询的功能:

foreach (string searchField in allFields) {
    innerExpr.Add(new WildcardQuery(new Term(searchField, searchParam)), Occur.SHOULD);
}

然后,将来,您只需向数组中添加/更改/删除字段名,而不必管理查询列表。

为了适应将来对索引的更改,您可以对该解决方案进行改进,即创建一个字符串数组变量来保存字段名,例如:

string[] allFields = new string[] {"company", "description", 
     "name", "posterName"};
这反过来将为您提供一个值,以便输入到解析器中:

MultiFieldQueryParser mfqp = new MultiFieldQueryParser(
     Version.LUCENE_30, allFields, analyzer);
以及通过字段进行迭代并使用一行添加通配符查询的功能:

foreach (string searchField in allFields) {
    innerExpr.Add(new WildcardQuery(new Term(searchField, searchParam)), Occur.SHOULD);
}

然后,在将来,您只需向数组中添加/更改/删除字段名,而不必管理查询列表。

如果其他人可以提供关于如何执行此操作的备选答案,我将选择该选项作为最佳选项。在那之前,我没有任何选择来选择我自己的,因为这是唯一的选择。我认为问题不在于查询,而在于分析器。您将它从空白改为标准,我认为这是您的解决方案。但我对Lucene也是新手:)有趣。我无法证实或拒绝,因为我记不起来了——为了让这项工作正常进行,我跳过了睡眠。@Adammiller术语查询部分在做什么?如果其他人能给出另一个答案,我会选择最好的答案。在那之前,我没有任何选择来选择我自己的,因为这是唯一的选择。我认为问题不在于查询,而在于分析器。您将它从空白改为标准,我认为这是您的解决方案。但我对Lucene也是新手:)有趣。我无法证实或拒绝,因为我记不起来了——我为了让它工作而跳过了睡眠。@Adammiller术语查询部分在做什么?