1713
December 9, 2018, 4:19pm
1
こんにちは。
タイトルにある方法をここしばらく探していまして、どうしても見つからず皆様のお知恵をお貸し頂けないでしょうか。
以下のように、フィールドが配列になっているドキュメントがあります。
{
"Description": "Jay Desc 1",
"Entities": [
{
"ID": "1234",
"NAME": "TAROU",
},
{
"ID": "1234_KANJI",
"NAME": "太郎",
},
{
"ID": "1234_RUBY",
"NAME": "たろう",
},
]
}
ここから、IDが1234_RUBYの要素を削除する場合、以下の方法があります。
POST /test/type/1/_update
{
"script": {
"lang": "painless",
"inline": "ctx._source.Entities.removeAll(Collections.singleton(params.Entities))",
"params" : {
"Entities":{
"ID": "1234_RUBY",
"NAME": "たろう",
}
}
}
}
ただしこの方法だと、削除したい要素のすべての情報(上記例だとIDとNAME両方)を指定する必要があります。
ですが、IDに"_RUBY"が含まれていることだけが分かっていて数字部分が判らない、且つ、NAMEには何が入っているか不明な場合、どのようにして削除することができるでしょうか。ID=".*_RUBY",NAME=".*"とかやってみたのですがうまくいきませんでした。
何卒宜しくお願い致します。
mnozawa
(Makoto Nozawa)
December 12, 2018, 4:26am
2
これでいかがでしょうか。
手元の環境ではうまくいきました。
正規表現でマッチングするのであればまた変わってきそうですね。
POST /test/type/1/_update
{
"script": {
"lang": "painless",
"source": "ctx._source.Entities.removeIf(item -> item.ID.contains(params.pattern));",
"params" : {
"pattern": "RUBY"
}
}
}
1 Like
1713
December 12, 2018, 4:42pm
3
mnozawa様
ありがとうございます!完璧に動作しました。
マッチする要素が複数あっても、forで回す必要なくすべてきれいに削除できますね!
さっそく全ドキュメントで実行したところ、こちらも大成功です。
POST /test/type/_update_by_query
{
"query": {
"match_all": { }
},
"script": {
"lang": "painless",
"source": "ctx._source.Entities.removeIf(item -> item.ID.contains(params.pattern));",
"params" : {
"pattern": "RUBY"
}
}
}
#ElasticsearchのリファレンスよりJAVAの勉強が必要なのだろうか…とちょっと思っちゃいました
1713
December 22, 2018, 5:29am
4
度々申し訳ありません。
上記の続きですが、どうしてもうまくいかなくなってしまいまして、また教えていただけませんでしょうか。
前述のインデックスに以下のデータを入れたのですが、text型でマッピングしている
フォールドに「数値」として保存されてしまい、containsメソッドが失敗してしまいました。
{
"Description": "Jay Desc 1",
"Entities": [
{
"ID": 5678, ← ダブルクォーテーションをつけないと数値として保存される
"NAME": "TAROU"
},
{
"ID": "5678_KANJI",
"NAME": "太郎"
},
{
"ID": "5678_RUBY",
"NAME": "たろう"
}
]
}
いろいろ試していて、値をインクリメントできたことから数値である
こと気がついたのですが、なぜマッピング定義に反した型で保存できて
しまうのでしょうか。
また、このような場合、保存されている型を判定してエラーを回避するには
どのようにすれば良いでしょうか。
よろしくお願いいたします。
1713
December 23, 2018, 11:11am
5
すみません。自己解決しましたので一応ご報告として書いておきます。
以下のようにすることで、IDフィールドに整数が入っていてもエラーなく
実行できるようになりました。
POST /test/type/_update_by_query
{
"query": {
"match_all": { }
},
"script": {
"lang": "painless",
"source": "ctx._source.Entities.removeIf(item -> item.ID.toString().contains(params.pattern));",
"params" : {
"pattern": "RUBY"
}
}
}
text型に整数値が保存されている理由ですが、色々試した結果、「保存はtext型で入っているけど、
スクリプトで演算しようとすると、整数型とみなされる」ということなんじゃないかと思っています。
そこで演算時にStringにキャストすれば行けるのかと思い、上記の方法を思いつきました。
これが最適な方法かは全くわかりませんが…
system
(system)
Closed
January 20, 2019, 11:11am
6
This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.