2017-09-14 11 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/ES/REST를 사용한다면 이것은 내가 한 일이다.

나는 elasticsearch와 내 장고 앱을 연결하기 위해 elasticsearch-dsl 문서 (http://elasticsearch-dsl.readthedocs.io/en/latest/)를 따랐다. 그런 다음 rest_framework_elasticsearch 패키지 프레임 워크를 사용하여 뷰를 생성했습니다.

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 기능을 사용하고 있는지 확인하거나 목록에서 귀하의 의견의 일부를 건너 것입니다.

본인은 내 새 필터를 사용합니다.

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

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

파이썬 쪽에서 작업하는 것이 훨씬 쉽고 빠릅니다.