Skip to main content
 首页 » 编程设计

Elasticsearch嵌套对象管理

2022年07月19日127小虾米

Elasticsearch嵌套对象管理

1. 索引包括嵌套对象、

嵌套对象可以表达关系型数据库中一对多关系,同时增强检索能力。下面定义human索引包括cats嵌套对象,定义mapping:

PUT human 
{ 
  "mappings": { 
    "properties": { 
      "name": { 
        "type": "text" 
      }, 
      "cats": { 
        "type": "nested", 
        "properties": { 
          "colors": { 
            "type": "integer" 
          }, 
          "name": { 
            "type": "text" 
          }, 
          "breed": { 
            "type": "keyword" 
          } 
        } 
      } 
    } 
  } 
} 

Human有name属性和嵌套对象cats;cats包括下面三个属性:colors,name,breed

下面增加一个文档带有三个cat:

PUT /human/_doc/1 
{ 
  "name": "iridakos", 
  "cats": [ 
    { 
      "colors": 1, 
      "name": "Irida", 
      "breed": "European Shorthair" 
    }, 
    { 
      "colors": 2, 
      "name": "Phoebe", 
      "breed": "European" 
    }, 
    { 
      "colors": 3, 
      "name": "Nino", 
      "breed": "Aegean" 
    } 
  ] 
} 

查询文档确认添加:

GET /human/_doc/1 

返回结果:

{ 
  "_index" : "human", 
  "_type" : "_doc", 
  "_id" : "1", 
  "_version" : 1, 
  "_seq_no" : 0, 
  "_primary_term" : 1, 
  "found" : true, 
  "_source" : { 
    "name" : "iridakos", 
    "cats" : [ 
      { 
        "colors" : 1, 
        "name" : "Irida", 
        "breed" : "European Shorthair" 
      }, 
      { 
        "colors" : 2, 
        "name" : "Phoebe", 
        "breed" : "European" 
      }, 
      { 
        "colors" : 3, 
        "name" : "Nino", 
        "breed" : "Aegean" 
      } 
    ] 
  } 
} 

2. 维护嵌套对象

下面讨论如何对嵌套对象进行添加、修改、删除。

2.1. 添加嵌套对象

增加一个嵌套对象Leon。使用_updateapi:

POST /human/_update/1 
{ 
  "script": { 
    "source": "ctx._source.cats.add(params.cat)", 
    "params": { 
      "cat": { 
        "colors": 4, 
        "name": "Leon", 
        "breed": "Persian" 
      } 
    } 
  } 
} 

通过ctx._source.cats访问嵌套对象,返回collection,执行add方法增加新的cat。新cat属性通过params传入。

2.2. 删除嵌套对象

我们现在删除cat集合中删除Nino:

POST /human/_update/1 
{ 
  "script": { 
    "source": "ctx._source.cats.removeIf(cat -> cat.name == params.cat_name)", 
    "params": { 
      "cat_name": "Nino" 
    } 
  } 
} 

通过ctx._source.cats返回集合,通过removeIf方法有条件删除条目。removeIf方法参数为Predicate,确定是否要删除特定条目。predicate在集合中每个条目上执行,返回值为Boolean,true则删除,我们示例通过判断name属性使用与参数cat_name相同。

2.3. 修改嵌套对象

修改所有cat的属性breeds 为 European 修改为 European Shorthair:

POST /human/_update/1 
{ 
  "script": { 
    "source": "def targets = ctx._source.cats.findAll(cat -> cat.breed == params.current_breed); for(cat in targets) { cat.breed = params.breed }", 
    "params": { 
      "current_breed": "European", 
      "breed": "European Shorthair" 
    } 
  } 
} 

ctx._source.cats返回集合,在集合上执行findAll方法选择想要的条目,Predicate参数设定条件。查询内容和修改内容都通过参数传入。

2.4. 运用多个条件更新多个属性

现在使用更加灵活脚本实现更复杂的示例。目标对象需要多个条件进行匹配,更新多个属性。
加入我们想修改cat属性breed为Persian,colors为3,修改为Aegean和3 。脚本如下:

POST /human/_update/1 
{ 
  "script": { 
    "source": "def targets = ctx._source.cats.findAll(cat -> { for (condition in params.conditions.entrySet()) { if (cat[condition.getKey()] != condition.getValue()) { return false; } } return true; }); for (cat in targets) { for (change in params.changes.entrySet()) { cat[change.getKey()] = change.getValue() } }", 
    "params": { 
      "conditions": { 
        "breed": "Persian", 
        "colors": 4 
      }, 
      "changes": { 
        "breed": "Aegean", 
        "colors": 3 
      } 
    } 
  } 
} 

格式化代码:

def targets = ctx._source.cats.findAll(cat -> { 
                                         for (condition in params.conditions.entrySet()) { 
                                           if (cat[condition.getKey()] != condition.getValue()) { 
                                             return false; 
                                           } 
                                         } 
                                         return true; }); 
for (cat in targets) { 
 for (change in params.changes.entrySet()) { 
   cat[change.getKey()] = change.getValue() 
 } 
} 

通过params.conditions参数确定条件查询目标对象,通过params.changes参数传入修改后的值。

3. 总结

本文介绍Elasticsearch的嵌套对象,通过示例说明如何使用脚本维护嵌套对象。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/105860225
阅读延展