programing

배열에 주어진 값이 포함 된 항목 필터링

projobs 2021. 1. 19. 21:00
반응형

배열에 주어진 값이 포함 된 항목 필터링


다음과 같은 문서 세트가 있습니다.

{
    tags:['a','b','c']
    // ... a bunch properties
}

제목에 명시된대로 : Nest를 사용하여 지정된 태그가 포함 된 모든 문서를 필터링하는 방법이 있습니까?

예를 들어 위의 레코드는 [ 'c', 'd']와 일치합니다.

아니면 여러 "OR"을 수동으로 만들어야합니까?


편집 : 아래의 bitset 내용은 흥미로운 읽을 수 있지만 대답 자체는 약간 날짜가 있습니다. 이 기능 중 일부는 2.x에서 변경됩니다. 또한 Slawek terms은이 경우 쿼리가 검색을 건조시키는 쉬운 방법 이라고 다른 답변에서 지적합니다 . 현재 모범 사례를 위해 마지막에 리팩토링되었습니다. -nz

과 함께 Bool 쿼리 (또는 다른 쿼리와 함께 필터)가 필요할 것입니다 should.

부울 쿼리는 세 가지 주요 속성이 있습니다 must, should하고 must_not. 이들 각각은 다른 쿼리 또는 쿼리 배열을 허용합니다. 절 이름은 매우 자명합니다. 귀하의 경우 should절은 목록 필터를 지정할 수 있으며, 그중 하나와 일치하면 찾고있는 문서가 반환됩니다.

문서에서 :

must절이 없는 부울 쿼리 에서 하나 이상의 should절이 문서와 일치해야합니다. 일치시킬 최소 should 절의 수는 minimum_should_match매개 변수를 사용하여 설정할 수 있습니다 .

다음은 Bool 쿼리가 개별적으로 표시 될 수있는 예입니다.

{
  "bool": {
    "should": [
      { "term": { "tag": "c" }},
      { "term": { "tag": "d" }}
    ]
  }
}

다음은보다 일반적인 용도의 필터링 된 쿼리 내의 필터로서 Bool 쿼리의 또 다른 예입니다 .

{
  "filtered": {
    "query": {
      "match": { "title": "hello world" }
    },
    "filter": {
      "bool": {
        "should": [
          { "term": { "tag": "c" }},
          { "term": { "tag": "d" }}
        ]
      }
    }
  }
}

Bool을 쿼리 (예 : 일치 점수에 영향을주기 위해)로 사용하든 필터 (예 : 점수가 매겨 지거나 사후 필터링되는 히트 수를 줄이기 위해)로 사용하는지 여부는 요구 사항에 따라 주관적입니다.

일반적으로 And / Or / Not을 사용할 이유가없는 경우 (이러한 이유가 존재하는 경우) Or 필터 대신 Bool을 사용하는 것이 좋습니다 . Elasticsearch 블로그에는 각각의 다양한 구현에 대한 자세한 정보와 Bool을 And / Or / Not보다 선호하거나 그 반대의 경우에 대한 좋은 예가 있습니다.

Elasticsearch 블로그 : Elasticsearch 필터 Bitset의 모든 것

리팩토링 된 쿼리로 업데이트 ...

이제 모든 것을 중단하고 terms쿼리는 위의 모든 것의 DRYer 버전입니다. 후드 아래의 쿼리 유형과 관련하여 올바른 작업을 수행하고 옵션을 사용하여 bool+ 와 동일하게 작동 하며 전반적으로 약간 더 간결합니다.shouldminimum_should_match

마지막 쿼리가 약간 리팩터링되었습니다.

{
  "filtered": {
    "query": {
      "match": { "title": "hello world" }
    },
    "filter": {
      "terms": {
        "tag": [ "c", "d" ],
        "minimum_should_match": 1
      }
    }
  }
}

일부 작업을 저장해야하는 용어 쿼리있습니다. 다음은 문서의 예입니다.

{
  "terms" : {
      "tags" : [ "blue", "pill" ],
      "minimum_should_match" : 1
  }
}

Under hood는 부울 should를 생성합니다. 따라서 기본적으로 위와 동일하지만 더 짧습니다.

해당 용어 필터도 있습니다.

따라서 쿼리를 요약하면 다음과 같이 보일 수 있습니다.

{
  "filtered": {
    "query": {
      "match": { "title": "hello world" }
    },
    "filter": {
      "terms": {
        "tags": ["c", "d"]
      }
    }
  }
}

태그 수가 많을수록 길이가 상당히 달라질 수 있습니다.


이것은 오래된 질문이지만 최근에 직접이 문제에 직면했으며 여기에있는 일부 답변은 현재 사용되지 않습니다 (댓글이 지적했듯이). 따라서 여기서 우연히 발견 한 다른 사람들의 이익을 위해 :

term쿼리가 역순 인덱스에 지정된 정확한 용어를 찾을 수 있습니다 :

{
  "query": {
   "term" : { "tags" : "a" }
} 

문서에서 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

또는 terms주어진 배열에 지정된 항목과 모든 문서를 일치 시키는 쿼리 를 사용할 수 있습니다 .

{
  "query": {
   "terms" : { "tags" : ["a", "c"]}
} 

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html

One gotcha to be aware of (which caught me out) - how you define the document also makes a difference. If the field you're searching in has been indexed as a text type then Elasticsearch will perform a full text search (i.e using an analyzed string).

If you've indexed the field as a keyword then a keyword search using a 'non-analyzed' string is performed. This can have a massive practical impact as Analyzed strings are pre-processed (lowercased, punctuation dropped etc.) See (https://www.elastic.co/guide/en/elasticsearch/guide/master/term-vs-full-text.html)

To avoid these issues, the string field has split into two new types: text, which should be used for full-text search, and keyword, which should be used for keyword search. (https://www.elastic.co/blog/strings-are-dead-long-live-strings)

ReferenceURL : https://stackoverflow.com/questions/28001632/filter-items-which-array-contains-any-of-given-values

반응형