文章目录
1. jion查询简介
join查询主要是针对有parent/child文档查询的需求,parent和child是两个独立存储的doc,在es中有两种mapping可以实现,一种是nested mapping,一种是join mapping
2. nested mapping对应的查询
1.使用样例简介
PUT /my-index-000001
{
"mappings": {
"properties": {
"obj1": {
"type": "nested"
}
}
}
}
GET /my-index-000001/_search
{
"query": {
"nested": {
"path": "obj1",
"query": {
"bool": {
"must": [
{ "match": { "obj1.name": "blue" } },
{ "range": { "obj1.count": { "gt": 5 } } }
]
}
},
"score_mode": "avg"
}
}
}
可以有的参数
path: 要查询的nested object的属性路径
query: 想要在nested object中进行的查询,如果查到了,会返回root parent doc.
score_mode: 如果一个nested query 命中了root parent doc中的多个child,那么root parent doc的得分如果通过这些child计算出来,
avg: (默认)所有child的平均值
max: max(child_score)
min: min(child_score)
mone: parent doc的score设置为0
sum: sum(child_score)
ignore_unmapped:忽略unmapped path, 默认为false,在path是一个unmapped field的时候会报错
2.多层级的nested query
PUT /drivers
{
"mappings": {
"properties": {
"driver": {
"type": "nested",
"properties": {
"last_name": {
"type": "text"
},
"vehicle": {
"type": "nested",
"properties": {
"make": {
"type": "text"
},
"model": {
"type": "text"
}
}
}
}
}
}
}
}
PUT /drivers/_doc/1
{
"driver" : {
"last_name" : "McQueen",
"vehicle" : [
{
"make" : "Powell Motors",
"model" : "Canyonero"
},
{
"make" : "Miller-Meteor",
"model" : "Ecto-1"
}
]
}
}
PUT /drivers/_doc/2?refresh
{
"driver" : {
"last_name" : "Hudson",
"vehicle" : [
{
"make" : "Mifune",
"model" : "Mach Five"
},
{
"make" : "Miller-Meteor",
"model" : "Ecto-1"
}
]
}
}
执行查询
GET /drivers/_search
{
"query": {
"nested": {
"path": "driver",
"query": {
"nested": {
"path": "driver.vehicle",
"query": {
"bool": {
"must": [
{ "match": { "driver.vehicle.make": "Powell Motors" } },
{ "match": { "driver.vehicle.model": "Canyonero" } }
]
}
}
}
}
}
}
}
response
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.7349272,
"hits" : [
{
"_index" : "drivers",
"_type" : "_doc",
"_id" : "1",
"_score" : 3.7349272,
"_source" : {
"driver" : {
"last_name" : "McQueen",
"vehicle" : [
{
"make" : "Powell Motors",
"model" : "Canyonero"
},
{
"make" : "Miller-Meteor",
"model" : "Ecto-1"
}
]
}
}
}
]
}
}
3. join field的使用
1. has_child 查询简介
has_child查询需要通过join mapping的field来进行支持,这个查询主要是查询拥有某些child的parent文档
PUT /my-index-000001
{
"mappings": {
"properties": {
"my-join-field": {
"type": "join",
"relations": {
"parent": "child" # 这里可以是任何字符串,前面的代表parent,后面的代表child
}
}
}
}
}
GET /_search
{
"query": {
"has_child": {
"type": "child",
"query": {
"match_all": {}
},
"max_children": 10,
"min_children": 2,
"score_mode": "min"
}
}
}
这个文档因为对child的查询是match_all,所以会返回所有有child的parent doc。
参数
type: join field中child的名字(这里刚好也定义为了child,可以是是任何字符串)
query: 想要查询的child,会返回这些child 对应的parent doc
max_child: 设置的话则parent的child数量不能超过这个值
min_child: 设置的话则parent的child数量要大于这个值
score_mode: 如果一个 query 命中了parent doc中的多个child,那么 parent doc的得分如果通过这些child计算出来,
avg: (默认)所有child的平均值
max: max(child_score)
min: min(child_score)
mone: parent doc的score设置为0
sum: sum(child_score)
1. 排序sort
如果想要排序的话,只能使用function_score 来通过_score排序, 不能用正常的sort语法
GET /_search
{
"query": {
"has_child": {
"type": "child",
"query": {
"function_score": {
"script_score": {
"script": "_score * doc['click_count'].value"
}
}
},
"score_mode": "max"
}
}
}
2. has_parent查询简介
has_parent查询需要通过join mapping的field来进行支持,这个查询主要是查询拥有某些parent的child文档
PUT /my-index-000001
{
"mappings": {
"properties": {
"my-join-field": {
"type": "join",
"relations": {
"parent": "child"
}
},
"tag": {
"type": "keyword"
}
}
}
}
GET /my-index-000001/_search
{
"query": {
"has_parent": {
"parent_type": "parent",
"query": {
"term": {
"tag": {
"value": "Elasticsearch"
}
}
}
}
}
}
会在parent中查询tag value为Elasticsearch 的doc,然后查询这些doc对应的child doc
参数
type: join field中parent的名字(这里刚好也定义为了parent,可以是是任何字符串)
query: 想要查询的parent,会返回这些parent 对应的parent doc
score: 默认是false,false的话会忽略parent的相关性得分,ture的话parent的相关性得分会给child使用
1. 排序sort
如果想要排序的话,只能使用function_score 来通过_score排序, 不能用正常的sort语法
GET /_search
{
"query": {
"has_parent": {
"parent_type": "parent",
"score": true,
"query": {
"function_score": {
"script_score": {
"script": "_score * doc['view_count'].value"
}
}
}
}
}
}
3. parent id查询
PUT /my-index-000001
{
"mappings": {
"properties": {
"my-join-field": {
"type": "join",
"relations": {
"my-parent": "my-child"
}
}
}
}
}
PUT /my-index-000001/_doc/1?refresh
{
"text": "This is a parent document.",
"my-join-field": "my-parent"
}
PUT /my-index-000001/_doc/2?routing=1&refresh
{
"text": "This is a child document.",
"my_join_field": {
"name": "my-child",
"parent": "1"
}
}
GET /my-index-000001/_search
{
"query": {
"parent_id": {
"type": "my-child",
"id": "1"
}
}
}
type: 关系中child的名称
id: parent doc的id
返回对应的parent的child doc集合