将Elasticsearch请求从Kibana转换为elasticsearch-dsl

时间:2017-01-14 03:06:07

标签: python elasticsearch-dsl

最近从AWS Elasticsearch Service(使用Elasticsearch 1.5.2)迁移到Elastic Cloud(目前使用的是Elasticsearch 5.1.2)。很高兴我做到了,但随着这一变化,出现了更新版本的Elasticsearch和更新的API。苦苦挣扎着绕过新的求职方式。以前,我可以或多或少地从Kibana的“Elasticsearch Request Body”复制/粘贴,调整一些东西,运行elasticsearch.Elasticsearch.search()并得到我期望的结果。

这是我来自Kibana的Elasticsearch Request Body(为了简洁起见,删除了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范围内的内容。

对弹性搜索-dsl和ES 5.1.2的处理方式完全不熟悉,所以我知道我有很多需要学习的东西。我究竟做错了什么?在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我现在没有运行弹性搜索,但查询看起来像您想要的(除了public static String file = "sokoban.txt"; 之外,您总能看到通过查看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

希望这会有所帮助......