簡體   English   中英

使用python在elasticsearch-dsl中聚合一個字段

[英]aggregate a field in elasticsearch-dsl using python

有人能告訴我如何編寫Python語句來匯總(總結和計算)有關我文檔的內容嗎?


腳本

from datetime import datetime
from elasticsearch_dsl import DocType, String, Date, Integer
from elasticsearch_dsl.connections import connections

from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search, Q

# Define a default Elasticsearch client
client = connections.create_connection(hosts=['http://blahblahblah:9200'])

s = Search(using=client, index="attendance")
s = s.execute()

for tag in s.aggregations.per_tag.buckets:
    print (tag.key)

OUTPUT

File "/Library/Python/2.7/site-packages/elasticsearch_dsl/utils.py", line 106, in __getattr__
'%r object has no attribute %r' % (self.__class__.__name__, attr_name))
AttributeError: 'Response' object has no attribute 'aggregations'

是什么造成的? “聚合”關鍵字是錯誤的嗎? 我需要導入一些其他包嗎? 如果“出勤”索引中的文檔有一個名為emailAddress的字段,我如何計算哪些文檔具有該字段的值?

首先。 我現在注意到我在這里寫的,實際上沒有定義聚合。 關於如何使用它的文檔對我來說不是很易讀。 用我上面寫的,我會擴展。 我正在更改索引名稱以獲得更好的示例。

from datetime import datetime
from elasticsearch_dsl import DocType, String, Date, Integer
from elasticsearch_dsl.connections import connections

from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search, Q

# Define a default Elasticsearch client
client = connections.create_connection(hosts=['http://blahblahblah:9200'])

s = Search(using=client, index="airbnb", doc_type="sleep_overs")
s = s.execute()

# invalid! You haven't defined an aggregation.
#for tag in s.aggregations.per_tag.buckets:
#    print (tag.key)

# Lets make an aggregation
# 'by_house' is a name you choose, 'terms' is a keyword for the type of aggregator
# 'field' is also a keyword, and 'house_number' is a field in our ES index
s.aggs.bucket('by_house', 'terms', field='house_number', size=0)

上面我們為每個門牌號創建一個桶。 因此,桶的名稱將是門牌號。 ElasticSearch(ES)將始終提供適合該存儲桶的文檔的文檔計數。 Size = 0表示使用所有結果,因為ES有一個默認設置只能返回10個結果(或者你的dev設置它做什么)。

# This runs the query.
s = s.execute()

# let's see what's in our results

print s.aggregations.by_house.doc_count
print s.hits.total
print s.aggregations.by_house.buckets

for item in s.aggregations.by_house.buckets:
    print item.doc_count

我之前的錯誤是認為彈性搜索查詢默認具有聚合。 您可以自己定義它們,然后執行它們。 然后您的回復可以與您提到的聚合器分開。

上面的CURL應如下所示:
注意:我為Google Chrome使用SENSE ElasticSearch插件/擴展程序/插件。 在SENSE中,您可以使用//來評論事物。

POST /airbnb/sleep_overs/_search
{
// the size 0 here actually means to not return any hits, just the aggregation part of the result
    "size": 0,
    "aggs": {
        "by_house": {
            "terms": {
// the size 0 here means to return all results, not just the the default 10 results
                "field": "house_number",
                "size": 0
            }
        }
    }
}

變通。 DSL的GIT上有人告訴我忘記翻譯,只是使用這種方法。 它更簡單,你可以在CURL中編寫棘手的東西。 這就是我稱之為解決方案的原因。

# Define a default Elasticsearch client
client = connections.create_connection(hosts=['http://blahblahblah:9200'])
s = Search(using=client, index="airbnb", doc_type="sleep_overs")

# how simple we just past CURL code here
body = {
    "size": 0,
    "aggs": {
        "by_house": {
            "terms": {
                "field": "house_number",
                "size": 0
            }
        }
    }
}

s = Search.from_dict(body)
s = s.index("airbnb")
s = s.doc_type("sleepovers")
body = s.to_dict()

t = s.execute()

for item in t.aggregations.by_house.buckets:
# item.key will the house number
    print item.key, item.doc_count

希望這可以幫助。 我現在在CURL中設計所有內容,然后使用Python語句剝離結果以獲得我想要的內容。 這有助於進行多級聚合(子聚合)。

我還沒有代表發表評論,但想對Matthew對VISQL關於from_dict的回答發表評論。 如果要維護搜索屬性,請使用update_from_dict而不是from_dict。

根據文檔 ,from_dict創建一個新的搜索對象,但update_from_dict將在適當的位置進行修改,如果搜索已經具有索引,使用等屬性,這就是您想要的

所以你想在搜索之前聲明查詢體,然后像這樣創建搜索:

query_body = {
    "size": 0,
    "aggs": {
        "by_house": {
            "terms": {
                "field": "house_number",
                "size": 0
            }
        }
    }
}

s = Search(using=client, index="airbnb", doc_type="sleep_overs").update_from_dict(query_body)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM