Elasticsearch 多级嵌套对象过滤和更新

Elasticsearch multilevel nested object filter and update

弹性搜索:6.3
我正在尝试通过过滤特定书籍来更新嵌套字段。以下是示例记录。

{  
   "StoreName":"test",
   "StoreID":"12435",
   "BookInfo":[  
      {  
         "Name":"Book1",
         "Comments":[  
            {  
               "date":"2019-01-07",
               "Comment":"this is a nice book"
            },
            {  
               "date":"2019-01-06",
               "Comment":"this is a nice book"
            },
            {  
               "date":"2019-01-04",
               "Comment":"this is a nice book"
            },
            {  
               "date":"2019-01-03",
               "Comment":"this is a nice book"
            }
         ],
         "UPC":2435466,

      },
      {  
         "Name":"Book2",
         "Comments":[  
            {  
               "date":"2019-01-07",
               "Comment":"this is a nice book"
            },
            {  
               "date":"2019-01-06",
               "Comment":"this is a nice book"
            },
            {  
               "date":"2019-01-04",
               "Comment":"this is a nice book"
            },
            {  
               "date":"2019-01-03",
               "Comment":"this is a nice book"
            }
         ],
         "UPC":576868345657,

      },

   }
]
} 

在这里,我们有多个商店,每个商店都有多本书。对于每本书,我们每天都会存储用户评论。我想通过检查该特定日期的评论是否已经存在,在 [BookInfo.Comments] 下添加日期和评论。如果它已经存在,那么我将需要跳过它,如果没有则附加新评论。 我尝试通过更新 API 来做到这一点,但我无法过滤特定书籍并从可用书籍列表中更新评论。有人可以帮我弄这个吗?提前致谢。

请参阅下文,查看您的相关文档,我如何创建映射、通过查询脚本进行更新以及响应如何显示。

映射:

PUT mybook
{
  "mappings": {
    "mydocs":{
      "properties":{
        "StoreName": {
          "type": "keyword"
        },
        "StoreID":{
          "type": "keyword"
        },
        "BookInfo":{
          "type": "nested",
          "properties": {
            "Comments" :{
              "type": "nested",
              "properties":{
                "date":{
                  "type": "date"
                },
                "Comment": {
                  "type": "text"
                }
              }
            },
            "Name": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}

查询:

以下是您需要的Update By Query

POST mybook/_update_by_query
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "StoreName": "test"
          }
        },
        {
          "term": {
            "StoreID": "12435"
          }
        },
        {
          "nested": {
            "path": "BookInfo",
            "query": {
              "term": {
                "BookInfo.Name": "Book1"
              }
            }
          }
        }
      ]
    }
  },
  "script": {
    "lang": "painless",
    "inline": """
      ArrayList list = ctx._source.BookInfo;
      for(int i=0; i<list.size();i++){
        HashMap myHashMap = list.get(i);
        boolean isPresent = false;
        for(int j=0; j<myHashMap.size();j++){
          String mybook = myHashMap.get(params.book_key);
          if(mybook==params.book_value)
          {
            ArrayList mylist = myHashMap.get("Comments");
            for(int k=0; k<mylist.size(); k++){
              HashMap existingMap = mylist.get(k);
              Iterator entries = existingMap.entrySet().iterator();
              while(entries.hasNext()){
                Map.Entry entry = (Map.Entry) entries.next();
                if(entry.getKey()==params.date_key && entry.getValue()==params.date_value){
                  isPresent = true
                }
              }  
            }

            if(!isPresent){
              HashMap myMap = new HashMap();
              myMap.put(params.date_key, params.date_value);
              myMap.put(params.comment_key, params.comment_value);
              mylist.add(myMap);
              isPresent = false;
            }
          }
        }
      }
    """,
    "params": {
      "book_key":   "Name",
      "book_value": "Book1",
      "date_key":   "date",
      "date_value": "2019-01-08",
      "comment_key": "Comment",
      "comment_value": "This is a new comment here"

  }}
}

总而言之,我正在尝试为具有 "Name:Book1""StoreId": "1234""StoreName": "test"

的书添加日期和评论

注意查询中的以下部分:

"params": {
      "book_key":   "Name",
      "book_value": "Book1",
      "date_key":   "date",
      "date_value": "2019-01-08",
      "comment_key": "Comment",
      "comment_value": "This is a new comment here"

}

这些是您需要将上述查询(根据您的要求)修改为 运行 的参数。

其余的无痛脚本是我建议您完成的,因为它就像普通 java 代码一样,我只是从 BookInfo 遍历它以达到所需document/fields 并添加 date/comment.

当然,请原谅我使用了这么多的迭代和循环。我建议更好的方法是在您的应用程序层中完全构建文档并 re-ingest 它。

回复:

{
  "_index": "mybook",
  "_type": "mydocs",
  "_id": "1",
  "_version": 44,
  "found": true,
  "_source": {
    "StoreName": "test",
    "StoreID": "12435",
    "BookInfo": [
      {
        "Comments": [
          {
            "date": "2019-01-07",
            "Comment": "this is a nice book"
          },
          {
            "date": "2019-01-06",
            "Comment": "this is a nice book"
          },
          {
            "date": "2019-01-04",
            "Comment": "this is a nice book"
          },
          {
            "date": "2019-01-03",
            "Comment": "this is a nice book"
          },
          {
            "date": "2019-01-08",
            "Comment": "This is a new comment here"
          }
        ],
        "UPC": 2435466,
        "Name": "Book1"
      },
      {
        "Comments": [
          {
            "date": "2019-01-07",
            "Comment": "this is a nice book"
          },
          {
            "date": "2019-01-06",
            "Comment": "this is a nice book"
          },
          {
            "date": "2019-01-04",
            "Comment": "this is a nice book"
          },
          {
            "date": "2019-01-03",
            "Comment": "this is a nice book"
          }
        ],
        "UPC": 576868345657,
        "Name": "Book2"
      }
    ]
  }
}

希望对您有所帮助!