elasticsearch - 有没有办法像其他编程语言一样用脚本迭代弹性数组文档

标签 elasticsearch elasticsearch-5 elasticsearch-dsl

Mapping

{
"supply": {
  "properties": {
    "rotation_list": {
      "type": "nested",
      "properties": {
        "project_end_date": {
          "type": "nested",
          "properties": {
            "end_date": {
              "type": "date",
              "format": "yyyy-MM-ddTHH:mm:ss"
            }
          }
        },
        "total_days": {
          "type": "integer"
        }
      }
    }
  }
}}

Data

{"rotation_list": [
{
  "project_end_date": [
    {
      "end_date": "2020-08-07"
    },
    {
      "end_date": "2020-06-07"
    }
  ],
  "total_days": 23
},
{
  "project_end_date": [
    {
      "end_date": "2020-08-07"
    }
  ],
  "total_days": 26
}]}

query

{"query": {
"bool": {
  "filter": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "rotation_list.project_end_date",
            "query": {
              "script": {
                "script": {
                  "lang": "groovy",
                  "inline": "import  org.elasticsearch.common.logging.*;logger=ESLoggerFactory.getLogger('myscript');def ratable =false;logger.info(doc['rotation_list.project_end_date.end_date'].values)"
                }
              }
            }
          }
        }
      ]
    }
  }
}}}

Log result

[INFO][myscript][1596758400000][INFO][myscript][1591488000000][INFO][myscript][1596758400000]

我不确定为什么会这样。有什么方法可以像 [1596758400000, 1591488000000] 和 [1596758400000] 那样迭代。 数据也是这样保存的。我在映射中也提到了嵌套类型。不知道为什么会这样返回。有什么方法可以像我已编制索引的原始文档一样进行迭代。

最佳答案

由于 nested 的性质,不可能在脚本查询中访问嵌套文档的嵌套邻居。每个(子)文档都被视为一个单独的文档——无论是在顶层还是在像您的 rotation_list.project_end_date 这样的对象数组中。

唯一允许访问嵌套字段的整个上下文的情况是在 script_fields 中——但不幸的是你不能通过它们查询——只能动态构建它们并检索它们:

使用上面的映射

GET supply_nested/_search
{
  "script_fields": {
    "combined_end_dates": {
      "script": {
        "lang": "painless",
        "source": "params['_source']['rotation_list'][0]['project_end_date']"
      }
    }
  }
}

仅当 rotation_list 单独嵌套而不是 project_end_date 时,才可以在脚本查询中进行迭代。在这里使用 7.x:

PUT supply_non_nested
{
  "mappings": {
    "properties": {
      "rotation_list": {
        "type": "nested",
        "properties": {
          "project_end_date": {
            "type": "object",
            "properties": {
              "end_date": {
                "type": "date",
                "format": "yyyy-MM-dd"
              }
            }
          },
          "total_days": {
            "type": "integer"
          }
        }
      }
    }
  }
}

同步文档:

POST supply_non_nested/_doc
{
  "rotation_list": [
    {
      "project_end_date": [
        {
          "end_date": "2020-08-07"
        },
        {
          "end_date": "2020-06-07"
        }
      ],
      "total_days": 23
    },
    {
      "project_end_date": [
        {
          "end_date": "2020-08-07"
        }
      ],
      "total_days": 26
    }
  ]
}

使用 painless 而不是 groovy 进行查询,因为在这种情况下它更安全且更简洁:

GET supply_non_nested/_search
{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "rotation_list",
                "query": {
                  "script": {
                    "script": {
                      "lang": "painless",
                      "inline": "Debug.explain(doc['rotation_list.project_end_date.end_date'])"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

屈服

...
"reason": {
          ...
          "to_string": "[2020-06-07T00:00:00.000Z, 2020-08-07T00:00:00.000Z]",
          "java_class": "org.elasticsearch.index.fielddata.ScriptDocValues$Dates",
        }
...

从您的代码片段中并不能完全清楚您试图在查询中实现的目标。能详细说说吗?

关于elasticsearch - 有没有办法像其他编程语言一样用脚本迭代弹性数组文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62826771/

相关文章:

elasticsearch - 参数的 Elasticsearch 对象关联查询

amazon-web-services - 如果它在 ec2 实例中运行,如何检查我的 Elasticsearch 是否启动

ruby - 如何在Elasticsearch中结合3个术语?

database - 导出工具以在 Elasticsearch 2.3.5 索引之间通过查询复制数据

elasticsearch - 如何在Elasticsearch中对多值字段进行桶聚合

elasticsearch - 如何调整match_all查询?

elasticsearch - 轮胎术语过滤器不起作用

elasticsearch - 覆盖Elasticsearch Recipe 中的属性

ssl - 如何在 elasticsearch 5.5 中设置 server.name?

elasticsearch - 面向单词的完成建议器 (ElasticSearch 5.x)