Nested内のオブジェクト数で絞り込みする方法について

お世話になっております。
以前質問させて頂いた「Nested内のオブジェクト数でソートする方法について」の延長上にあるのですが、

以下のようなnestedフィールドのインデックスを作成し、

PUT my_index
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      }
    }
  }
}

nested内のオブジェクト数が1,2,3となるようにドキュメントを入れた際に、

PUT my_index/_doc/1
{
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    }
  ]
}
PUT my_index/_doc/2
{
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
PUT my_index/_doc/3
{
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    },
    {
      "first" : "hoge",
      "last" :  "fuga"
    }
  ]
}

これらをuserフィールド内のオブジェクト数で絞って取得することは可能でしょうか?
ex. オブジェクト数が2つ以上のドキュメントを取得する

script queryを用いて試しているのですが、なかなか取得出来ず苦戦しております。
※Elasticsearchのバージョンは6.5になります

お手数をおかけしますが、もし方法がありましたらご教示頂ければ幸いです。
以上、よろしくお願い致します。

Script Queryで頑張ろうとするのは少々しんどそうでしたので、代わりの案を紹介したいです。

似たような例がありました。
@spinscale さんがいうには、オブジェクト数ならオブジェクト数を別フィールドに格納しておけば、より速いクエリが使えるし、コストの高いクエリ(=Scriptクエリ)を使う必要はない、と書かれています。

今回の例ですと、このようにアプローチするのはダメでしょうか?

↓ userオブジェクト部分の数え上げと、別フィールドに値を格納するパイプラインを作成

PUT _ingest/pipeline/my_pipeline
{
    "description": "count user nested object size",
    "processors": [
      {
        "script": {
          "source": """
            if (ctx.user != null) {
              ctx.user_count = ctx.user.size();  
            }
            
          """
        }
      }
    ]
}

ドキュメント登録時に、パイプラインを指定して登録する。

PUT my_index/_doc/1?pipeline=my_pipeline
{
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    }
  ]
}

作成されるIndexで、user_countにuserオブジェクトの数(今回は1)が入る。

{
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "user_count" : 1,
          "user" : [
            {
              "last" : "Smith",
              "first" : "John"
            }
          ]
        }
      }

このようにしておけば、単純な単一フィールドに対する数値の検索になるため、検索クエリが簡単に作れるかと思います。

Pipelineを使ってuser_count部分を追加しているのは、既存のデータ投入部分に大きな変更を入れなくてもよくて、Pipelineを指定するだけの変更でできそう、ということをお伝えしたかったためです。

ご参考になれば幸いです。

ご回答ありがとうございます。パイプラインというのがあるんですね。
記載して頂いたようにパイプラインを作成してデータを投入するとuser_countが入ることが確認出来ました。
大変参考になりました。

ただ一点問題がありまして、実務上は user フィールド以外のフィールドが存在する状態で、
user の配列の要素数が変わることがあり、そのupdate時にパイプラインが使用出来ない点です。
※インデックスでないとパイプラインを指定出来ないようです

こうした場合ですとやはりuser_countは自前で入れた方が良さそうですね。

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.