ES 父子文档查询

父子文档的特点

1. 父/子文档是完全独立的。

2. 父文档更新不会影响子文档。

3. 子文档更新不会影响父文档或者其它子文档。

父子文档的映射与索引

1. 父子关系 type 的建立必须在索引新建或 update-mapping 时候确定好

PUT /company
{
  "mappings": {
    "branch": {},             //父文档 type
    "employee": {
      "_parent": {
        "type": "branch"      //子文档 type
      }
    }
  }
}

2. 父文档的索引和普通文档索引一样。

POST /company/branch/_bulk
{ "index": { "_id": "london" }}
{ "name": "London Westminster", "city": "London", "country": "UK" }

3. 子文档索引必须指定其对应的父文档 ID,作用:

  • 建立父子文档之间的关联
  • 确保子文档能够被索引到父文档所在分片(parent id 作为 route)
PUT /company/employee/1?parent=london     //指定 id = london 的父文档
{
  "name":  "Alice Smith",
  "dob":   "1970-10-24",
  "hobby": "hiking"
}

4. 如果要更改文档的父文档,不能仅仅 update 或者 reindex 旧文档(新的父文档可能在不同分片上),需要先删除旧文档再重新索引。

父子关系的应用

看到 parent-child 关系,我们很容易想到的是像 SQL 那样的各种 JOIN 操作——比如查询某个文档并一并取回所有的父或子文档等。

然而,ES 中不支持类似的 JOIN 查询。

在 ES 中的 parent-child 关系基本可以理解为仅仅是一个过滤条件,如下:

//查询某文档,只有该文档有"父文档"且满足一定条件才算匹配
{"has_parent": {                //文档是否有 parent
      "type": "branch",         //其 parent 所在 type 必须是 branch
      "query": {                //其 parent 必须满足以下 query 条件
        "match": {
          "country": "UK"
        }
      }
    }                           //如果满足以上条件,hit 该文档
}
//查询某文档,只有该文档有"子文档"且满足一定条件才算匹配
{
"has_child": {                       //文档是否有 child
      "type":       "employee",      //其 child所在 type 必须是 employee
      "query": {                     //其 parent 必须满足以下 query 条件
        "match": {
          "name": "Alice Smith"
        }
      }
    }                                //如果满足以上条件,hit 该文档
}

1. has_child:基于子文档的内容,查找父文档

//请求
GET /company/branch/_search
{
  "query": {
    "has_child": {                                //基于 child 的内容,查询满足条件的 parent 文档
      "type":       "employee",
      "query": {                                   //在 child 中执行 match query操作
        "match": {
          "name": "Alice Smith"
        }
      }
    }
  }
}
//结果
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "company",
        "_type": "branch",                     //注意!!!返回的是 parent 的文档
        "_id": "london",
        "_score": 1,
        "_source": {
          "name": "London Westminster",
          "city": "London",
          "country": "UK"
        }
      }
    ]
  }
}

2. has_parent:基于父文档的内容,查找子文档

//请求 GET /company/employee/_search
{
  "query": {
    "has_parent": {                       //基于 parent 的内容,查询满足条件的 child 文档
      "type": "branch",
      "query": {                             //在 parent 中执行 match query 查询
        "match": {
          "country": "UK"
        }
      }
    }
  }
}
//结果
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "company",
        "_type": "employee",              //注意!!!返回的是 child 的文档
        "_id": "1",
        "_score": 1,
        "_routing": "london",
        "_parent": "london",
        "_source": {
          "name": "Alice Smith",
          "dob": "1970-10-24",
          "hobby": "hiking"
        }
      }
    ]
  }
}

3. children aggregation:

时间: 2024-12-22 19:29:19

ES 父子文档查询的相关文章

Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)

Spring Data MongoDB 三:基本文档查询(Query.BasicQuery)(一) 学习MongoDB 六: MongoDB查询(游标操作.游标信息)(三) 一.简介 SpringData  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的find的操作,我们上一篇介绍了基本文档的查询,我们今天介绍分页查询,分页查询是返回到匹配文档的游标,可以随意修改查询限制.跳跃.和排序顺序的功能. 我

Spring Data MongoDB 三:基本文档查询(Query、BasicQuery)(一)

一.简介 Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我们介绍了对MongoDB的新增和删除, 今天我们要介绍Java代码实现对MongoDB实现查询操作. 我们回顾一下,我们在之前介绍了MongoDB的基本文档查询,MongoDB的查询语法: db.orders.find({{<field1>:<value1>,<field2>

SpringMVC MongoDB之“基本文档查询(Query、BasicQuery)”

一.简介 spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我们介绍了对MongoDB的新增和删除, 今天我们要介绍Java代码实现对MongoDB实现查询操作. 我们回顾一下,我们在之前介绍了MongoDB的基本文档查询,MongoDB的查询语法: db.orders.find({{<field1>:<value1>,<field2>

向量空间模型实现文档查询(Vector space model to realise document query)

xml中文档(query)的结构: <topic> <number>CIRB010TopicZH006</number> <title>科索沃難民潮</title> <question> 查詢科索沃戰爭中的難民潮情況,以及國際間對其採取的援助. </question> <narrative> 相關文件內容包括科省難民湧入的地點.人數,受安置的狀況,難民潮引發的問題,參與救援之國家與國際組織,其援助策略與行動內容

Java-Object类、JDK_API文档查询

1.Object类 同java.lang包下的类,可以直接拿过来用 Object类的方法: 1)toString方法 2.下载API文档 http://java.sun.com,下载Java SE document,解压下载的压缩包,就可以查看API文档了.

MongoDB快速入门学习笔记4 MongoDB的文档查询操作

先把student删除,再重新插入数据 > db.student.drop() true > db.student.insert([{ "_id" : 1, "name" : "zhangsan", "age": 27, "sex": 1 }, { "_id" : 2, "name" : "lisi", "age":

android API文档查询---context、toast、SharedPreferences

/*查阅api ---context1.abstract AssetManager     getAssets() Returns an AssetManager instance for the application's package. 得到assets目录下的资源 2.abstract File     getCacheDir() Returns the absolute path to the application specific cache directory on the fi

MongoDB查询集合中的文档

MongoDB查询集合中的文档 参考资料:http://blog.csdn.net/qq_36040184/article/details/54355085 测试: 集合中插入数据 > db.chenji.insert({"name":"张三","年纪":"三年级","年龄":"14"}) WriteResult({ "nInserted" : 1 }) >

学习MongoDB 五: MongoDB查询(数组、内嵌文档)(二)

一.简介 我们上一篇介绍了db.collection.find()可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段,我们今天介绍了对数组和内嵌文档的查询操作,尤其是对$elemMatch 同样可以用在find方法的第二个参数来限制返回数组内的元素,只返回我们需要的文档的介绍.我们经常在查询条件查询内嵌文档数组时,只需要返回主文档并返回内嵌文档数组中我们只需要的值,而不是把内嵌文档的数组都返回. 二.对数组根据条件查询  $all.$size.$slice.$e