【问题标题】:Return the most recent record from ElasticSearch index从 ElasticSearch 索引返回最近的记录
【发布时间】:2019-08-08 03:08:19
【问题描述】:

我想从 ElasticSearch 索引中返回最近的记录(前 1 条),类似于下面的 sql 查询;

SELECT TOP 1 Id, name, title 
FROM MyTable 
ORDER BY Date DESC;

这个可以吗?

【问题讨论】:

标签: elasticsearch


【解决方案1】:

您的文档映射中是否启用了_timestamp

{
    "doctype": {
        "_timestamp": {
            "enabled": "true",
            "store": "yes"
        },
        "properties": {
            ...
        }
    }
}

您可以在此处查看您的映射:

http://localhost:9200/_all/_mapping

如果是这样,我认为这可能适用于获取最新信息:

{
  "query": {
    "match_all": {}
  },
  "size": 1,
  "sort": [
    {
      "_timestamp": {
        "order": "desc"
      }
    }
  ]
}

【讨论】:

  • 至少对于我使用的客户端(Chrome "Advanced REST Client" 扩展),我必须将 '"size": 1' 的 "1" 放在双引号中才能生效.
  • 使用 _timestamp 字段和使用自定义时间戳字段有什么区别?
  • @castarco,启用后,_timestamp 会自动为您生成,因此您可以使用它,就像 mconlin 建议的那样,而不是添加您自己的。但是,从 2.0.0-beta2 开始,_timestamp 已被弃用,因此您应该使用自己的时间戳 :) elastic.co/guide/en/elasticsearch/reference/current/…
  • _timestamp 对我不起作用。但是@timestamp 做到了。
  • 我遇到以下错误:org.elasticsearch.index.mapper.MapperParsingException: Mapping definition for [_timestamp] has unsupported parameters: [store : yes]
【解决方案2】:

出于信息目的,_timestamp 自 2.0.0-beta2 起现已弃用。 在映射中使用date 类型。

来自date 数据类型文档的简单日期映射 JSON:

{
  "mappings": {
     "my_type": {
        "properties": {
          "date": {
          "type": "date" 
        }
      }
    }
  }
}

您还可以在date 中添加format 字段:

{
  "mappings": {
    "my_type": {
      "properties": {
        "date": {
          "type":   "date",
          "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
      }
    }
  }
}

【讨论】:

    【解决方案3】:

    使用按日期获取最后一个 ID(没有时间戳)

    示例网址http://localhost:9200/deal/dealsdetails/
    方法:POST

    查询:

    {
      "fields": ["_id"],
      "sort": [{
          "created_date": {
            "order": "desc"
          }
        },
        {
          "_score": {
            "order": "desc"
          }
        }
      ],
      "size": 1
    }
    

    结果:

    {
      "took": 4,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": null,
        "hits": [{
          "_index": "deal",
          "_type": "dealsdetails",
          "_id": "10",
          "_score": 1,
          "sort": [
            1478266145174,
            1
          ]
        }]
      }
    }
    

    【讨论】:

    • 如果您有一个可以在 doc 映射中引用的日期,但它不是 es 时间戳,这是一个不错的选择。我无法让它与 elasticsearch py 一起使用,所以我将使用我的 modified_on 文档日期。我对使用创建日期持怀疑态度,因为它不会随着文档更新而改变。
    【解决方案4】:

    您可以在日期字段和size=1 参数上使用sort。 有帮助吗?

    【讨论】:

    • 如果我们正在寻找最后一个拥有想要的第一级属性的文档,我们该怎么办?因为在某些情况下,我的索引/文档查询结果中有:_registered : { date : 2016-03-18, ..... _pending: { date: 2016-03-16, ... 它只会检索我_register 文档,因为它较新,但是当我尝试解析 _pending. 时,它会失败,因为密钥不是预期的。我们可以在搜索查询中指定它吗?谢谢!
    • 不知道。我不明白。你应该用一个例子来开启一个新的讨论吗?
    • 不,这没有帮助。一个示例值一千个网络查询。
    【解决方案5】:

    如果你使用 python elasticsearch5 模块或 curl:

    1. 确保插入的每个文档都有
      • 日期时间类型的时间戳字段
      • 并且您正在单调增加每个文档的时间戳值
    2. 从python你做的

      es = elasticsearch5.Elasticsearch('my_host:my_port')
      es.search(
          index='my_index', 
          size=1,
          sort='my_timestamp:desc'
          )
      

    如果您的文档没有插入任何日期时间类型的字段,那么我不相信您可以获得 N 个“最新”。

    【讨论】:

      【解决方案6】:

      我用@timestamp代替_timestamp

      {
          'size' : 1,
          'query': {
              'match_all' : {}
                  },
          "sort" : [{"@timestamp":{"order": "desc"}}]
      }
      

      【讨论】:

        【解决方案7】:

        自从最初提出并回答了这个问题以来,Elasticsearch 的一些内部工作方式已经发生了变化,尤其是在时间戳方面。这是一个完整的示例,展示了如何查询单个最新记录。在 ES 6/7 上测试。

        1) 告诉 Elasticsearch 将 timestamp 字段视为时间戳

        curl -XPUT "localhost:9200/my_index?pretty" -H 'Content-Type: application/json' -d '{"mappings":{"message":{"properties":{"timestamp":{"type":"date"}}}}}'
        

        2) 将一些测试数据放入索引中

        curl -XPOST "localhost:9200/my_index/message/1" -H 'Content-Type: application/json' -d '{ "timestamp" : "2019-08-02T03:00:00Z", "message" : "hello world" }'
        curl -XPOST "localhost:9200/my_index/message/2" -H 'Content-Type: application/json' -d '{ "timestamp" : "2019-08-02T04:00:00Z", "message" : "bye world" }'
        

        3) 查询最新记录

        curl -X POST "localhost:9200/my_index/_search" -H 'Content-Type: application/json' -d '{"query": {"match_all": {}},"size": 1,"sort": [{"timestamp": {"order": "desc"}}]}'
        

        4) 预期结果

        {
           "took":0,
           "timed_out":false,
           "_shards":{
              "total":5,
              "successful":5,
              "skipped":0,
              "failed":0
           },
           "hits":{
              "total":2,
              "max_score":null,
              "hits":[
                 {
                    "_index":"my_index",
                    "_type":"message",
                    "_id":"2",
                    "_score":null,
                    "_source":{
                       "timestamp":"2019-08-02T04:00:00Z",
                       "message":"bye world"
                    },
                    "sort":[
                       1564718400000
                    ]
                 }
              ]
           }
        }
        

        【讨论】:

          【解决方案8】:

          _timestamp 不适合我,

          这个查询对我有用:

          (如 mconlin 的回答)

          {
            "query": {
              "match_all": {}
            },
            "size": "1",
            "sort": [
              {
                "@timestamp": {
                  "order": "desc"
                }
              }
            ]
          }
          

          可能是微不足道的,但 _timestamp 答案没有给出错误但也不是一个好的结果......

          希望对某人有所帮助...

          (kibana/弹性 5.0.4)

          S.

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-03-19
            • 1970-01-01
            • 2018-01-09
            • 1970-01-01
            • 2020-01-07
            相关资源
            最近更新 更多