ElasticSearch多匹配子字符串搜索

时间:2019-07-26 18:03:22

标签: elasticsearch

我必须组合两个过滤器以符合要求: -r.status字段中的值的特定列表 -多个文本字段之一包含值。 结果查询(使用Nest,但没有关系)如下:

{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "isActive": {
                    "value": true
                  }
                }
              },
              {
                "nested": {
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "terms": {
                            "r.status": [
                              "VALUE_1",
                              "VALUE_2",
                              "VALUE_3"
                            ]
                          }
                        },
                        {
                          "bool": {
                            "should": [
                              {
                                "match": {
                                  "r.g.firstName": {
                                    "type": "phrase",
                                    "query": "SUBSTRING_VALUE"
                                  }
                                }
                              },
                              {
                                "match": {
                                  "r.g.lastName": {
                                    "type": "phrase",
                                    "query": "SUBSTRING_VALUE"
                                  }
                                }
                              }
                            ]
                          }
                        }
                      ]
                    }
                  },
                  "path": "r"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

还尝试了多重匹配查询:

{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "isActive": {
                    "value": true
                  }
                }
              },
              {
                "nested": {
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "terms": {
                            "r.status": [
                              "VALUE_1",
                              "VALUE_2",
                              "VALUE_3"
                            ]
                          }
                        },
                        {
                          "multi_match": {
                            "query": "SUBSTRING_VALUE",
                            "fields": [
                              "r.g.firstName",
                              "r.g.lastName"
                            ]
                          }
                        }
                      ]
                    }
                  },
                  "path": "r"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

FirstNameLastName在索引映射中配置为text

"firstName": {
  "type": "text"
},
"lastName": {
  "type": "text"
}

Elastic提供了许多全文本搜索选项:multi_matchphrasewildcards等。但是,在我的情况下,所有这些选项都无法在文本字段中查找子字符串。 (terms查询和isActive一个很好,我只是尝试只运行它们。)

我还有什么选择,或者我在哪里出错了?

UPD:组合通配符对我有用,但这种查询看起来很丑。寻找更优雅的解决方案。

1 个答案:

答案 0 :(得分:0)

elasticsearch方法是使用ngram令牌生成器。

ngram分析器将使用滑动窗口拆分您的术语。例如,输入“ Hello World”将生成以下术语:

  • Hel
  • 地狱
  • 你好
  • ell
  • 你好
  • ...
  • 糟糕
  • 世界
  • orl
  • ...

您可以配置滑动窗口的最小和最大尺寸(在示例中,最小尺寸为3)。生成子条款后,您可以在子字段中使用匹配查询。

另一方面,在must中使用filter很奇怪。如果您对分数感兴趣,则应始终使用must,否则请使用filter。阅读this article以获得很好的理解。