1. ホーム
  2. elasticsearch

[解決済み] 配列に指定された値のいずれかが含まれる項目のフィルタリング

2023-07-07 18:12:06

質問

私は以下のようなドキュメントのセットを持っています。

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

タイトルにある通りです。Nestを使って、与えられたタグのいずれかを含むすべてのドキュメントをフィルタリングする方法はありますか?

例えば、上記のレコードは['c','d']にマッチするでしょう。

それとも、複数の "OR"s を手動で構築する必要がありますか?

どのように解決するのですか?

編集:以下のbitsetのものは面白い読み物かもしれませんが、回答自体は少し古いです。この機能のいくつかは 2.x で変更されています。また、Slawek は別の回答で terms クエリは、この場合の検索をDRYにする簡単な方法です。現在のベストプラクティスのために最後にリファクタリングしました。-nz

おそらくあなたは ブールクエリ (あるいは、より可能性の高い フィルタ を別のクエリと一緒に使うこともできます)、そして should 節があります。

boolクエリには3つの主要なプロパティがあります。 must , should そして must_not . これらはそれぞれ別のクエリ、あるいはクエリの配列を受け付けます。句の名前はかなり自明です。 should 節はフィルターのリストを指定し、そのうちのどれかにマッチすれば探しているドキュメントが返されます。

docsから。

ブール型クエリで 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をクエリとして使うか(例えばマッチのスコアに影響を与える)、フィルタとして使うか(例えば、その後スコアやポストフィルタリングされるヒットを減らす)は、要件によって主観的に判断されます。

一般に、Bool を使用することが望ましいです。 またはフィルタ ただし、And/Or/Notを使用する理由がある場合はこの限りではありません(実際にそのような理由は存在します)。Elasticsearchのブログには、それぞれの実装の違いや、And/Or/NotよりもBoolを使う方が良い場合、またその逆の場合の良い例についての情報が掲載されています。

Elasticsearchのブログです。 Elasticsearchのフィルタビットセットについて

リファクタリングされたクエリで更新...

さて、すべての その を抜きにすると terms クエリは、上記のすべてのクエリの DRYer バージョンです。これはフードの下にあるクエリのタイプに関して正しいことを行い、その動作は bool + should を使用して minimum_should_match というオプションがあり、全体的にもう少し簡潔です。

最後のクエリを少しリファクタリングしたものがこちらです。

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