Elasticsearch嵌套对象管理

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的嵌套对象,通过示例说明如何使用脚本维护嵌套对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值