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.