【问题标题】:How to retreive all the records from elasticsearch in rails如何从rails中的elasticsearch中检索所有记录
【发布时间】:2020-08-01 20:12:48
【问题描述】:

您可以从弹性搜索中获得的文档数量有上限(即 10000)。我们可以使用“滚动”来检索所有记录。有谁知道如何将其嵌入代码中?

有这个方法滚动

https://github.com/elastic/elasticsearch-ruby/blob/4608fd144277941003de71a0cdc24bd39f17a012/elasticsearch-api/lib/elasticsearch/api/actions/scroll.rb

但我不知道如何使用它。你能解释一下如何使用它吗?

我已经尝试过“扫描”。但 Elasticsearch 不再支持它。

# Open the "view" of the index
response = client.search index: 'test', search_type: 'scan', scroll: '5m', size: 10

# Call `scroll` until results are empty
while response = client.scroll(scroll_id: response['_scroll_id'], scroll: '5m') and not 
   response['hits']['hits'].empty? do
      puts response['hits']['hits'].map { |r| r['_source']['title'] }
end

【问题讨论】:

    标签: ruby-on-rails ruby api elasticsearch rubygems


    【解决方案1】:

    来自 elastic 官方文档的段落:

    我们不再推荐使用滚动 API 进行深度分页。如果 您需要在分页时保留索引状态 10,000 次点击,使用带有时间点的 search_after 参数 (坑)。

    Scroll Official Doc Link

    我推荐使用分页。

    你可以使用

    点击次数的限制是为了提高性能,你可以使用分页,它的速度要快得多。

    通过这种方式,您可以将起点与form 键一起使用,或将search_aftersort 和PIT 键一起使用(防止结果不一致的时间点)。并且您可以确定您点击 size 键 10 以获得更快的查询时间。

    Pagination Official Doc Link

    用于实例化 PIT ID:

    POST /test/_pit?keep_alive=1m
    

    用于实例化分页:

    GET /test/_search
    {
      "size": 10,
      "query": {
        "match" : {
          "user.id" : "elkbee"
        }
      },
      "pit": {
        "id":  "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", 
        "keep_alive": "1m"
      },
      "sort": [ 
        {"@timestamp": {"order": "asc", "format": "strict_date_optional_time_nanos", "numeric_type" : "date_nanos" }}
      ]
    }
    

    在分页中获取其余数据: 结果中有排序键,放在search_after

    GET /test/_search
    {
      "size": 10,
      "query": {
        "match" : {
          "user.id" : "elkbee"
        }
      },
      "pit": {
        "id":  "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", 
        "keep_alive": "1m"
      },
      "sort": [
        {"@timestamp": {"order": "asc", "format": "strict_date_optional_time_nanos"}}
      ],
      "search_after": [                                
        "2021-05-20T05:30:04.832Z", #you can find this value from sort key in response 
        4294967298
      ],
      "track_total_hits": false                        
    }
    

    【讨论】:

      【解决方案2】:

      您的代码应该可以工作,但正如您提到的,search_typescan 参数不是必需的。我只是用一些测试数据在本地运行它并且它有效:

      # scroll.rb
      require 'elasticsearch'
      
      client = Elasticsearch::Client.new
      
      response = client.search(index: 'articles', scroll: '10m')
      scroll_id = response['_scroll_id']
      while response['hits']['hits'].size.positive?
        response = client.scroll(scroll: '5m', body: { scroll_id: scroll_id })
        puts(response['hits']['hits'].map { |r| r['_source']['title'] })
      end
      

      输出:

      $ ruby scroll.rb                                                                                         
      Title 297                                                                                                
      Title 298                                                                                                
      Title 299                                                                                                
      Title 300
      ...
      

      您可以随意调整scroll 参数的值,但类似的方法也应该适合您。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-02
        • 1970-01-01
        • 2015-03-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多