python - ElasticSearch-过滤嵌套对象而不影响 “parent”对象

标签 python elasticsearch kibana elasticsearch-dsl

我有一个Blog对象的ElasticSearch映射,其中包含一个用于评论的嵌套字段。这样,用户可以向上面显示的博客内容添加评论。评论字段具有发布的标志,该标志确定评论是可以由其他用户还是仅由主要用户查看。

"blogs" :[
{
     "id":1,
     "content":"This is my super cool blog post",
     "createTime":"2017-05-31",
      "comments" : [
            {"published":false, "comment":"You can see this!!","time":"2017-07-11"}
       ]
},
{
     "id":2,
     "content":"Hey Guys!",
     "createTime":"2013-05-30",
     "comments" : [
               {"published":true, "comment":"I like this post!","time":"2016-07-01"},
               {"published":false, "comment":"You should not be able to see this","time":"2017-10-31"}
       ]
},
{
     "id":3,
     "content":"This is a blog without any comments! You can still see me.",
     "createTime":"2017-12-21",
     "comments" : None
},
]

我希望能够过滤评论,以便每个博客对象仅显示True评论。我想展示每个博客,而不仅仅是展示真实评论的博客。我在网上找到的所有其他解决方案似乎都在影响我的博客对象。有没有办法在不影响所有博客查询的情况下过滤掉注释对象?

因此,上面的示例将在查询后返回,如下所示:
"blogs" :[
{
     "id":1,
     "content":"This is my super cool blog post",
     "createTime":"2017-05-31",
      "comments" : None # OR EMPTY LIST 
},
{
     "id":2,
     "content":"Hey Guys!",
     "createTime":"2013-05-30",
     "comments" : [
               {"published":true, "comment":"I like this post!","time":"2016-07-01"}
       ]
},
{
     "id":3,
     "content":"This is a blog without any comments! You can still see me.",
     "createTime":"2017-12-21",
     "comments" : None
},
]

该示例仍显示没有评论或错误评论的博客。

这可能吗?

我一直在使用来自此示例的嵌套查询:ElasticSearch - Get only matching nested objects with All Top level fields in search response

但是此示例会影响博客本身,并且不会返回仅包含错误评论或没有评论的博客。

请帮忙:)谢谢!

最佳答案

好的,因此发现,显然没有办法使用Elasticsearch查询来执行此操作。但是我想出了一种在django / python上做到这一点的方法(这是我所需要的)。我不确定是否有人需要此信息,但是如果您需要此信息,并且您正在使用Django / ES / REST,这就是我所做的。

我遵循了elasticsearch-dsl文档(http://elasticsearch-dsl.readthedocs.io/en/latest/)将elasticsearch与我的Django应用程序连接。然后,我使用rest_framework_elasticsearch包框架来创建 View 。

要创建只查询Elasticsearch项目列表中True嵌套属性的Mixin,请创建rest_framework_elastic.es_mixins ListElasticMixin对象的mixin子类。然后按照下面的步骤在新的mixin中覆盖es_representation定义。

class MyListElasticMixin(ListElasticMixin):
    @staticmethod
    def es_representation(iterable):

        items = ListElasticMixin.es_representation(iterable)

        for item in items:
            for key in item:
                if key == 'comments' and item[key] is not None:
                    for comment in reversed(item[key]):
                        if not comment['published']:
                            item[key].remove(comment)

        return items

确保在注释的for循环中使用reversed函数,否则将跳过列表中的某些注释。

我在 View 中使用了这个新过滤器。
class MyViewSet(MyListElasticMixin, viewsets.ViewSet):
   # Your view code here

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

在python端执行此操作绝对更容易且可行。

关于python - ElasticSearch-过滤嵌套对象而不影响 “parent”对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46224546/

相关文章:

python ldap.LDAPError 对象拒绝访问字典

python - 如何创建一个在后台运行的程序?

python - ElasticSearch,size参数不适用于helpers.scan函数

python - 如何使用背景图片设置QTableWidget左上角?

Python:使用字典理解/生成器计算列表中的出现次数

c# - NEST中的NOT LIKE查询

elasticsearch - 如何在 Elasticsearch 中返回以特定字母或特定字母开头的字段的结果?

elasticsearch - 将 Kafka 主题标题显示为 Kibana 中的字段,logstash add_field?

ElasticSearch:嵌套桶聚合

elasticsearch - 基于日志级别的 kibana logstash 表行颜色