>

알고있는 한 Elasticsearch에서 다음과 같은 작업을 수행 할 수있는 방법이 없습니다 :

SELECT * FROM myindex
GROUP BY agg_field1, agg_field2, agg_field3 // aggregation
ORDER BY order_field1, order_field2, order_field3 // sort
LIMIT 1000, 5000 // paginate -- get page 6 of size 1000 records

이와 관련된 몇 가지 관련 문서는 다음과 같습니다.

  • https ://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-bucket-terms-aggregation.html
  • https ://discuss.elastic.co/t/elasticsearch-aggregation-order-by-hit-score-with-partitions/102228
  • https://github.com/elastic/elasticsearch/issues/21487

Elasticsearch에서 위의 작업을 수행 할 수있는 방법이 있습니까? 우리가 가진 한 가지 한계는 10M 이상의 레코드를 절대 가질 수 없기 때문에 메모리 오류가 발생하지 않아야한다는 것입니다. 내 생각은 다음과 같이하는 것이 었습니다.

  • 집계 쿼리 수행
  • 결과 수 가져 오기
  • 원하는 결과와 페이지 크기에 따라 N 개의 세그먼트로 분할
  • 위 세그먼트로 쿼리를 다시 실행

이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 답변/제안에서 위의 SQL 쿼리를 ES에서 수행하는 방법과 관련된 샘플 코드를 게시 할 수 있습니까?

<시간>

이 질문에 대한 업데이트로서 다음과 같이 테스트 할 공개 인덱스가 있습니다 :

# 5.6
e=Elasticsearch('https://search-testinges-fekocjpedql2f3rneuagyukvy4.us-west-1.es.amazonaws.com')
e.search('testindex')
# 6.4 (same data as above)
e = Elasticsearch('https://search-testinges6-fycj5kjd7l5uyo6npycuashch4.us-west-1.es.amazonaws.com')
e.search('testindex6')

만개의 레코드가 있습니다. 다음으로 자유롭게 테스트하십시오.

내가 원하는 쿼리는 다음과 같습니다 (sql) :

SELECT * FROM testindex
GROUP BY store_url, status, title
ORDER BY title ASC, status DESC
LIMIT 100 OFFSET 6000

즉, 집계 결과를 여러 집계로 정렬하고 오프셋을 얻으려고합니다.


  • 답변 # 1

    와이즈 비즈  집계는 여러 필드로 그룹화 한 다음 결과를 페이지 매김 할 수 있으므로 여기에 도움이 될 수 있습니다. 당신이 할 수없는 유일한 것은 주어진 오프셋에서 뛰어 오르는 것입니다. 그러나 필요한 경우 클라이언트 코드에서 반복하여 그렇게 할 수 있습니다.

    다음은이를 수행하기위한 샘플 쿼리입니다.

    composite
    
    

    응답에서 POST testindex6/_search { "size": 0, "aggs": { "my_buckets": { "composite": { "size": 100, "sources": [ { "store": { "terms": { "field": "store_url" } } }, { "status": { "terms": { "field": "status", "order": "desc" } } }, { "title": { "terms": { "field": "title", "order": "asc" } } } ] }, "aggs": { "hits": { "top_hits": { "size": 100 } } } } } } 를 보게 될 것입니다  구조 :

    after_key
    
    

    다음과 같은 후속 쿼리에 사용해야하는 일종의 커서입니다.

     "after_key": {
        "store": "http://google.com1087",
        "status": "OK1087",
        "title": "Titanic1087"
      },
    
    

    그리고 그것은 당신에게 다음 100 버킷을 줄 것입니다. 이게 도움이 되길 바랍니다.

    업데이트:

    전체 버킷 수를 알고 싶다면 { "size": 0, "aggs": { "my_buckets": { "composite": { "size": 100, "sources": [ { "store": { "terms": { "field": "store_url" } } }, { "status": { "terms": { "field": "status", "order": "desc" } } }, { "title": { "terms": { "field": "title", "order": "asc" } } } ], "after": { "store": "http://google.com1087", "status": "OK1087", "title": "Titanic1087" } }, "aggs": { "hits": { "top_hits": { "size": 100 } } } } } }  집계는 그 숫자를 제공하지 않습니다. 그러나 composite 이후  집계는 소스에있는 모든 필드의 데카르트 곱일뿐입니다.]] cardinality] (https://www.elastic.co/guide/en/elasticsearch/를 반환하여 총 수의 근사값을 얻을 수 있습니다. composite 에서 사용되는 각 필드의 reference/current/search-aggregations-metrics-cardinality-aggregation.html)  집계하고 곱하기

    composite
    
    

    "aggs": { "my_buckets": { "composite": { ... } }, "store_cardinality": { "cardinality": { "field": "store_url" } }, "status_cardinality": { "cardinality": { "field": "status" } }, "title_cardinality": { "cardinality": { "field": "title" } } } 에서 얻은 수치를 곱하여 총 버킷 수를 얻을 수 있습니다. store_cardinality  그리고 status_cardinality  함께 또는 적어도 그 근사치 (높은 카디널리티 필드에서는 잘 작동하지 않지만 카디널리티 낮은 필드에서는 잘 작동 함)

  • 답변 # 2

    필드 축소가 답입니다.

    필드 축소 기능은 특정 필드에서 적중을 그룹화 할 때 사용됩니다 (ag_field 별 그룹에서와 같이).

    Elastic 6 이전에 필드를 그룹화하는 방법은 집계를 사용하는 것입니다. 이 방법은 효율적인 페이징을 수행 할 수있는 능력이 부족했습니다.

    그러나 이제는 탄성에 의해 상자에서 필드 붕괴가 제공되어 매우 쉽습니다.

    아래는 위의 링크에서 가져온 필드 축소가있는 샘플 쿼리입니다.

    title_cardinality
    
    

    }

    GET /twitter/_search { "query": { "match": { "message": "elasticsearch" } }, "collapse" : { "field" : "user", "inner_hits": { "name": "last_tweets", "size": 5, "sort": [{ "date": "asc" }] }, "max_concurrent_group_searches": 4 }, "sort": ["likes"]

  • 이전 numbers - 우리는 어떻게 총계를 결정할 수 있습니까? 하이브 테이블 용 버킷
  • 다음 파이썬을 사용하여 데이터를 업로드하는 동안 SQL Server에서 테이블이 생성되지 않습니다