お世話になっております。
以前質問させて頂いた「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になります
お手数をおかけしますが、もし方法がありましたらご教示頂ければ幸いです。
以上、よろしくお願い致します。
tsgkdt
(tsgkdt)
November 12, 2019, 4:44am
2
Script Queryで頑張ろうとするのは少々しんどそうでしたので、代わりの案を紹介したいです。
Have you thought of using an ingest processor that checks the value height and width at index time and stores the result in another field? Then you would have fast queries as you do not need to run an expensive script query at all.
Of course this only makes sense if you have a limited number of such checks.
--Alex
似たような例がありました。
@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は自前で入れた方が良さそうですね。
system
(system)
Closed
December 12, 2019, 4:55am
4
This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.