2017-09-14 226 views
1

对于包含注释的嵌套字段的博客对象,我有一个ElasticSearch映射。这样用户就可以向上面显示的博客内容添加评论。注释字段具有已发布的标志,用于确定注释是否可以被其他用户查看,或者仅由主要用户查看。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 
}, 
] 

我希望能够过滤评论,所以只有真正的评论将显示为每个博客对象。我想展示每一个博客,而不仅仅是那些有真正意见的博客。我在网上找到的所有其他解决方案似乎都会影响我的博客对象。有没有办法在不影响所有博客查询的情况下过滤掉评论对象?

所以上面的例子将查询后也返回:

"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

但是这个例子影响了自己的博客,并不会返回只有虚假评论或没有评论的博客。

请帮忙:)谢谢!

回答

0

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

我遵循elasticsearch-dsl文档(http://elasticsearch-dsl.readthedocs.io/en/latest/)将elasticsearch与我的Django应用程序连接起来。然后,我使用rest_framework_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 

确保您使用reversed功能中的评论循环,否则你会跳过一些在列表中您的意见。

这个我在我看来使用这个新的过滤器。

class MyViewSet(MyListElasticMixin, viewsets.ViewSet): 
    # Your view code here 

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

在python方面做它肯定更容易和工作。