0

最近从 AWS Elasticsearch Service(使用 Elasticsearch 1.5.2)迁移到 Elastic Cloud(当前使用 Elasticsearch 5.1.2)。很高兴我做到了,但随着这种变化而来的是更新版本的 Elasticsearch 和更新的 API。努力让我了解请求东西的新方式。以前,我可以或多或少地从 Kibana 的“Elasticsearch 请求正文”中复制/粘贴,调整一些东西,运行 elasticsearch.Elasticsearch.search() 并得到我所期望的。

这是我来自 Kibana 的 Elasticsearch 请求正文(为简洁起见,删除了 Kibana 通常插入的一些无关内容):

{
  "size": 500,
  "sort": [
    {
      "Time.ISO8601": {
        "order": "desc",
        "unmapped_type": "boolean"
      }
    }
  ],
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "Message\\ ID: 2003",
            "analyze_wildcard": true
          }
        },
        {
          "range": {
            "Time.ISO8601": {
              "gte": 1484355455678,
              "lte": 1484359055678,
              "format": "epoch_millis"
            }
          }
        }
      ],
      "must_not": []
    }
  },
  "stored_fields": [
    "*"
  ],
  "script_fields": {},
}

现在我想用 elasticsearch-dsl 来做,因为这似乎是推荐的方法(而不是使用 elasticsearch-py)。我如何将以上内容翻译成elasticsearch-dsl?

这是我到目前为止所拥有的:

from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search, Q

client = Elasticsearch(
        hosts=['HASH.REGION.aws.found.io/elasticsearch'],
        use_ssl=True,
        port=443,
        http_auth=('USER','PASS')
    )

s = Search(using=client, index="emp*")
s = s.query("query_string", query="Message\ ID:2003", analyze_wildcards=True)
s = s.query("range", **{"Time.ISO8601": {"gte": 1484355455678, "lte": 1484359055678, "format": "epoch_millis"}})
s = s.sort("Time.ISO8601")

response = s.execute()

for hit in response:
    print '%s %s' % (hit['Time']['ISO8601'], hit['Message ID']) 

我上面写的代码没有给我我所期望的。获取包含与“Message\ ID:2003”不匹配的内容的结果,并且它也给了我请求的 Time.ISO8601 范围之外的东西。

elasticsearch-dsl 和 ES 5.1.2 的做事方式是全新的,所以我知道我有很多东西要学。我究竟做错了什么?在此先感谢您的帮助!

4

1 回答 1

1

我现在没有运行弹性搜索,但查询看起来像你想要的(你总是可以看到通过查看生成的查询s.to_dict()),但转义\符号除外。在原始查询中,它被转义了,但在 python 中,由于转义不同,结果可能会有所不同。

我强烈建议您的字段中不要有空格,并使用比以下更结构化的查询query_string

s = Search(using=client, index="emp*")
s = s.filter("term", message_id=2003)
s = s.query("range", Time__ISO8601={"gte": 1484355455678, "lte": 1484359055678, "format": "epoch_millis"})
s = s.sort("Time.ISO8601")

请注意,我还更改query()filter()以稍微加快速度,并在字段名称关键字参数中使用__而不是。将自动将其扩展为..elasticsearch-dsl.

希望这可以帮助...

于 2017-01-15T00:38:46.180 回答