【问题标题】:Elasticsearch DSL: filter, then aggregate in pythonElasticsearch DSL:过滤,然后在 python 中聚合
【发布时间】:2019-11-01 05:13:52
【问题描述】:

我需要过滤Elasticsearch 索引中的文档,然后按字段聚合它们。这是我正在尝试做的代码:

import elasticsearch
from elasticsearch_dsl import Search, Q, Index, MultiSearch
es_client = elasticsearch.Elasticsearch([url],
        timeout=30, retry_on_timeout=True)
project_ids=['CSI'] 
family_ids=['SF6140691_WES_CIDR'] 
sample_ids=['S1379354_CIDR'] 
gene_symbols=['GLTPD1', 'CCNL2', 'MRPL20'] 

genes_filter = Q('bool', must=[Q('terms', project_id=project_ids),
                                   Q('terms', family_id=family_ids),
                                   Q('terms', sample_id=sample_ids),
                                   Q('terms', gene_symbol=gene_symbols)])
search = Search(using=es_client, index="GENES_DATA")
search = search.filter(genes_filter).execute()
results = search.aggs.bucket('by_family', 'terms', field='family_id', size=0)

目前我收到以下错误:

'{!r} 对象没有属性 {!r}'.format(self.class.name, name)) AttributeError:“条款”对象没有属性“执行”

我尝试切换过滤和聚合,尝试在最后做execute(),但它没有帮助。如何实现这种简单的转变 - filtering + aggregation?我发现了单独进行聚合或单独过滤的示例,但在一个查询中找不到两者。

【问题讨论】:

    标签: python-2.7 elasticsearch elasticsearch-dsl


    【解决方案1】:

    而不是

    search = search.filter(genes_filter)
    results = search.aggs.bucket('by_family', 'terms', field='family_id', size=0)
    

    你应该有:

    search = search.filter(genes_filter)
    search.aggs.bucket('by_family', 'terms', field='family_id', size=0)
    results = search.execute()
    

    首先添加过滤器,然后定义聚合,最后执行搜索。

    【讨论】:

    • 问题是存储桶只给了我找到的文件的姓氏和数量,而不是整个对象。有没有办法获得以下结果,因为这是我需要的:[{family_id_1: [doc_1, doc_2, ...]}, {family_id_2: [doc_8, doc_9, ...]}?我需要一个普通的group_by,而不仅仅是文档数量
    • 常规分组也不会给你行,只是你分组的值和你决定的任何聚合函数。如果要检索存储桶中的文档,请使用 top_hits 聚合 - elastic.co/guide/en/elasticsearch/reference/current/…
    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 2019-12-31
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多