【问题标题】:Elasticsearch : search document with conditional filterElasticsearch:使用条件过滤器搜索文档
【发布时间】:2016-05-27 19:01:06
【问题描述】:

我的索引中有两个文档(相同类型):

{
    "first_name":"John",
    "last_name":"Doe",
    "age":"24",
    "phone_numbers":[
        {
            "contract_number":"123456789",
            "phone_number":"987654321",
            "creation_date": ...
        },
        {
            "contract_number":"123456789",
            "phone_number":"012012012",
            "creation_date": ...
        }
    ]
}

{
    "first_name":"Roger",
    "last_name":"Waters",
    "age":"36",
    "phone_numbers":[
        {
            "contract_number":"546987224",
            "phone_number":"987654321",
            "creation_date": ...,
            "expired":true
        },
        {
            "contract_number":"87878787",
            "phone_number":"55555555",
            "creation_date": ...
        }
    ]
}

客户想要执行全文搜索。好的,这里没问题

我的问题: 在此全文搜索中,有时用户会按 phone_number 进行搜索。在这种情况下,有一个 参数,例如 expired=true

示例: 第一个客户端搜索请求:"987654321" expired 不存在或设置为 false

--> 结果:仅第一个文档

第二个客户端搜索请求:"987654321" expired 设置为 true

--> 结果:两个文件

我怎样才能做到这一点?

这是我的映射:

{
"user": {
    "_all": {
        "auto_boost": true,
        "omit_norms": true
    },
    "properties": {
        "phone_numbers": {
            "type": "nested",
            "properties": {
                "phone_number": {
                    "type": "string"
                },
                "creation_date": {
                    "type": "string",
                    "index": "no"
                },
                "contract_number": {
                    "type": "string"
                },
                "expired": {
                    "type": "boolean"
                }
            }
        },
        "first_name":{
            "type": "string"
        },
        "last_name":{
            "type": "string"
        },
        "age":{
            "type": "string"
        }
    }
}

}

谢谢!

MC

编辑:

我试过这个查询:

{
"query": {
    "filtered": {
        "query": {
            "query_string": {
                "query": "987654321",
                "analyze_wildcard": "true"
            }
        },
        "filter": {
            "nested": {
                "path": "phone_numbers",
                "filter": {
                    "bool": {
                        "should":[
                           {
                             "bool": {
                                "must": [
                                  {
                                    "term": {
                                        "phone_number": "987654321"
                                    }
                                },
                                {
                                    "missing": {
                                        "field": "expired"
                                    }
                                }
                              ]
                            }       
                          },
                          {
                            "bool": {
                                "must_not": [
                                    {
                                        "term": {
                                            "phone_number": "987654321"
                                        }
                                    }
                                ]
                            }       
                         }
                        ]
                    }
                }
             }
        }
    }
}}

但是我得到了两个文件而不是只得到第一个

【问题讨论】:

  • 您希望对上述两种情况有两个不同的查询。
  • 感谢您的评论。我如何检测到客户端在 phone_number 字段上执行搜索?这应该是没有高级功能的全文搜索
  • 您将获得 2 个文档,因为这两个条件都满足。您有一个文档的 phone_number 缺少过期字段,还有一个文档 phone_number 和过期字段为 true
  • 我在查询中尝试执行的操作:如果 phone_number 匹配,则检查 phone_number 是否已过期,然后过滤此文档。如果电话号码不匹配,则不要过滤文档

标签: elasticsearch full-text-search


【解决方案1】:

你很亲密。尝试使用mustshould 的组合,其中must 子句确保phone_number 匹配搜索值,should 子句确保expired 字段丢失或设置为@987654327 @。例如:

{
  "query": {
    "filtered": {
      "query": {
        "query_string": {
          "query": "987654321",
          "analyze_wildcard": "true"
        }
      },
      "filter": {
        "nested": {
          "path": "phone_numbers",
          "query": {
            "filtered": {
              "filter": {
                "bool": {
                  "must": [
                    {
                      "term": {
                        "phone_number": "987654321"
                      }
                    }
                  ],
                  "should": [
                    {
                      "missing": {
                        "field": "expired"
                      }
                    },
                    {
                      "term": {
                        "expired": false
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
}

我使用您的映射和示例文档运行了这个查询,它返回了 John Doe 的一个文档,正如预期的那样。

【讨论】:

  • 如果客户端执行此搜索:“John”怎么办? must 子句不再匹配大小写。
猜你喜欢
  • 2019-04-25
  • 2019-09-19
  • 2014-09-08
  • 2018-08-29
  • 2012-08-30
  • 1970-01-01
  • 2017-02-15
  • 2018-06-22
  • 2021-11-10
相关资源
最近更新 更多