【问题标题】:Is there any way we can apply "and" condition to the "terms filter" in Elastic Search?有什么方法可以将“and”条件应用于 Elastic Search 中的“terms filter”?
【发布时间】:2021-01-05 01:09:49
【问题描述】:

在下面的过滤器查询中,它会找到包含任何提到的术语的文档。但我正在寻找只匹配所有条款的记录。 my_languages 是我索引中的一个数组字段。有什么简单的方法吗?我可以单独添加术语过滤器并且可以做到,但是我可以将任何简单的“添加”条件应用于这些术语。谢谢你

GET user_info/_search?pretty
    {
      "size": 30,
      "from": 0,
      "query": {
        "bool": {
          "filter": [
            {
              "terms": {
                "my_languages": [
                  8728431,
                  872854,
                  872845
                ]
              }
            }
          ]
        }
      }
    }

映射

  PUT user_info
    {
      "settings": {
        "number_of_shards": 1,
        "max_ngram_diff": 35
      },
      "mappings": {
        "properties": {
          "id": {
            "type": "keyword"
          },
          "email": {
            "type": "text"
          },
          "my_languages": {
            "type": "keyword"
          },
          "updated_by": {
            "type": "keyword"
          }
        }
      }
    }

测试数据

POST /user_info/_doc/
{
  "id": 10,
  "email": 2020,
  "my_languages": [
    8728431,
    872854,
    872845
  ]
}

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    你需要做一个布尔查询

    {
      "query": {
        "bool": {
          "must": [ 
            {
              "match": {
                "my_languages": "8728431"
              }
            },
            {
              "match": {
                "my_languages": "872845"
              }
            }
    ,
            {
              "match": {
                "my_languages": "872854"
              }
            }
          ]
        }
      }
    }
    

    您可以使用查询字符串

    {
      "size": 30,
      "from": 0,
      "query": {
        "query_string": {
          "query": "(8728431) AND (872854) AND (872845)",
          "default_field": "my_languages"
        }
      }
    }
    

    如果你真的想传递一个数组,你也可以使用脚本,但你必须先对性能进行基准测试,这似乎可行:

    {
      "query": {
        "bool": {
          "must": {
            "match_all": {}
          },
          "filter": {
            "bool": {
              "must": {
                "script": {
                  "script": {
                    "lang": "painless",
                    "source": "def x = doc['my_languages']; def list_to_check = ['8728431', '872854', '872845']; def do_not_return = true; for(int i = 0; i < list_to_check.length; i++) { if(!x.contains(list_to_check[i])) {do_not_return = false;}} return do_not_return;"
                  }
                }
              }
            }
          }
        }
      }
    }
    

    【讨论】:

    • 感谢@LeBigCat 的回复,我添加了映射和测试数据,请检查。谢谢。
    • 对不起,即使有匹配的记录,它也没有得到任何记录。再次感谢
    • 哦,这是一个数组,我的错,我编辑答案
    • 谢谢@LeBigCat,是的,我可以做到。我在我的问题中提到了它。但是有什么方法可以直接传递一个数组并做到这一点?如果我有 20 个项目,这将成为一个很大的混乱查询。
    • 你不能,如果你想传递一个数组,我发现的唯一方法是脚本(已编辑)。我看到的最后一个解决方案是使用 copy_to 功能,将数组的所有元素复制到文本字段中,并使用 match / minimumshouldmatch 100% 查询。
    猜你喜欢
    • 2022-10-06
    • 2017-10-17
    • 2023-04-03
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多