【问题标题】:in NEST, how do I dynamically build a query from a list of terms?在 NEST 中,如何从术语列表动态构建查询?
【发布时间】:2015-01-28 06:30:41
【问题描述】:

假设我的用户提供了我收集到数组/列表中的搜索词列表,现在我想使用 MatchPhrase 将这些 OR-wise 组合到 NEST 查询中。我该怎么做? (单个)搜索词的代码如下所示:

var search = client.Search<ElasticRequirement>(s => s
.Query(q =>
    q.MatchPhrase(m => m.OnField(f => f.Title).Query(term.ToLower()).Slop(slop))
    || q.MatchPhrase(m => m.OnField(f => f.Description).Query(text).Slop(slop))
    )
   .LowercaseExpandedTerms()
   .Explain()
   .Query(q => q.Fuzzy(f => f.PrefixLength(1).OnField(c => c.Title).OnField(c => c.Description)))
);

这很好,但我需要为每个提供的搜索词应用一次相同的 MatchPhrase 过滤器。非常感谢任何帮助。

【问题讨论】:

    标签: elasticsearch nest


    【解决方案1】:

    您可以使用 bool should 表达式动态构建查询。我将在下面提供完整的解决方案。使用适当的参数调用BuildQuery() 方法。

    ISearchResponse<ElasticRequirement> BuildQuery(IElasticClient client, IEnumerable<string> terms, int slop)
    {
        return client.Search<ElasticRequirement>(s => s
            .Query(q => q
                .Bool(b => b
                    .Should(terms.Select(t => BuildPhraseQueryContainer(q, t, slop)).ToArray())))
            .LowercaseExpandedTerms()
            .Explain()
            .Query(q => q.Fuzzy(f => f.PrefixLength(1).OnField(c => c.Title).OnField(c => c.Description))));
    }
    
    QueryContainer BuildPhraseQueryContainer(QueryDescriptor<ElasticRequirement> qd, string term, int slop)
    {
        return qd.MatchPhrase(m => m.OnField(f => f.Title).Query(term.ToLower()).Slop(slop)) ||
            qd.MatchPhrase(m => m.OnField(f => f.Description).Query(term.ToLower()).Slop(slop));
    }
    

    对于terms = {"term1", "term2", "term3"}slop = 0,将由我的代码构建的Elasticsearch 搜索JSON 命令如下:

    {
      "explain": true,
      "query": {
        "bool": {
          "should": [
            {
              "bool": {
                "should": [
                  {
                    "match": {
                      "title": {
                        "type": "phrase",
                        "query": "term1",
                        "slop": 0
                      }
                    }
                  },
                  {
                    "match": {
                      "description": {
                        "type": "phrase",
                        "query": "term1",
                        "slop": 0
                      }
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "should": [
                  {
                    "match": {
                      "title": {
                        "type": "phrase",
                        "query": "term2",
                        "slop": 0
                      }
                    }
                  },
                  {
                    "match": {
                      "description": {
                        "type": "phrase",
                        "query": "term2",
                        "slop": 0
                      }
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "should": [
                  {
                    "match": {
                      "title": {
                        "type": "phrase",
                        "query": "term3",
                        "slop": 0
                      }
                    }
                  },
                  {
                    "match": {
                      "description": {
                        "type": "phrase",
                        "query": "term3",
                        "slop": 0
                      }
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
    

    您可以调整此代码,使所有match 命令都在同一个should 节点下。我会让你自己弄清楚:)

    【讨论】:

    • 非常感谢您的详尽回答!
    • 这是一个绝妙的答案。真的帮了很多忙。
    • NEST v 5.2 抛出异常“querycontainer can only hold a single query already contains a matchphrasequerydescriptor”。
    猜你喜欢
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2014-10-07
    • 2015-11-19
    相关资源
    最近更新 更多