如何查找一个字段的值与另一个字段的值匹配的所有文档

时间:2015-05-08 14:45:03

标签: elasticsearch

我在文档中有两个字段,其中包含以下映射:

"field_a": {
    "type": "float"
},
"field_b": {
    "type": "float"
}

如何查找field_a的值与field_b的值匹配的所有文档?这是否可以禁用脚本?

2 个答案:

答案 0 :(得分:4)

基本上你需要一个脚本来执行它 - 即使禁用脚本也可能会有效,因为lucene表达式是完全沙盒化的:

GET /index/_search
{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "bool": {
          "must": [
            {
              "script": {
                "lang": "expression",
                "script": "doc['field_a'].value == doc['field_b'].value"
              }
            }
          ]
        }
      }
    }
  }
}

答案 1 :(得分:2)

  

禁用脚本可以实现吗?

这取决于禁用脚本的含义。如果您使用最新的1.4或1.5版本(目前为1.4.5和1.5.2)上的默认设置运行Elasticsearch,那么 仍然可以使用动态脚本,但它仅限于沙盒语言。

目前,唯一的内置和沙盒选项是Lucene Expressions,它是不是的默认脚本语言(Groovy在两个版本中都有,但它被认为是未安装的)。

因此,假设您尚未手动禁用动态脚本,那么您仍然可以使用Lucene Expressions来实现此目的,但有一些注意事项:

  1. Lucene Expressions 使用数字类型。特别是,它将所有内容视为double

    • 这意味着它目前无法与string一起使用。
  2. 您必须手动指定"expression"作为脚本语言。

  3. 从那里,创建这个脚本非常容易:

    GET /my-index/my-type/_search
    {
      "query" : {
        "filtered" : {
          "filter" : {
            "script" : {
              "script" : "doc[field_1].value == doc[field_2].value",
              "lang" : "expression",
              "params" : {
                "field_1" : "field_a",
                "field_2" : "field_b"
              }
            }
          }
        }
      }
    }
    

    我用"params"展示了它,表明你可以为多个字段重用相同的脚本。此外,您可以使用file-based scripting将此与Groovy脚本重用,从而避免动态脚本编写。从那里,您可以存储Groovy脚本(例如," equal_fields.groovy"),如链接所示:

    doc[field_1]?.value == doc[field_2]?.value
    

    然后,您可以以非常类似的方式重复使用它:

    GET /my-index/my-type/_search
    {
      "query" : {
        "filtered" : {
          "filter" : {
            "script" : {
              "file" : "equal_fields",
              "params" : {
                "field_1" : "field_a",
                "field_2" : "field_b"
              }
            }
          }
        }
      }
    }
    

    注意:长期来看,它应该是"script_file"而不是"file",但目前在允许脚本的不同API中并不总是干净。