写在后面
Elasticsearch(以下简称 ES)有个 copy_to
的性能,之前在一个我的项目中用到,感觉像是发现了一个神器。这个货色并不是像有些人说的是个语法糖。它用好了岂但能进步检索的效率,还能够简化查问语句。
根本用法介绍
间接上示例。
先看看 mapping,
PUT my_index
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {"type": "text"}
}
}
}
first_name 和 last_name 都指定了copy_to
,示意他们这两个字段的值都会复制到 full_name 上。写入两条文档看看,
PUT my_index/_doc/1
{
"first_name": "John",
"last_name": "Smith"
}
PUT my_index/_doc/2
{
"first_name": "Tom",
"last_name": "Cruise"
}
而后咱们在查问的时候,就能够指定从 full_name 这个字段查问了,
GET my_index/_search
{
"query": {
"match": {
"full_name": {
"query": "John Smith",
"operator": "and"
}
}
}
}
查问后果如下:
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.3862944,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3862944,
"_source" : {
"first_name" : "John",
"last_name" : "Smith"
}
}
]
}
如果没有应用 copy_to 的话,咱们须要指定两个字段查问,相似如下的语句:
GET my_index/_search
{
"query": {
"bool": {
"must": [
{"match": {"first_name": "John"}},
{"match": {"last_name": "Smith"}}
]
}
}
}
两种形式查问的后果是一样的。
进阶
聊完了根本用法,来看看一些高级的性能。如果说咱们想获取 full_name 的内容,有些业务场景下,咱们会须要返回这个字段,怎么办呢?其实很简略,如下所示,咱们在设置 mapping 的时候加上 store:true
即可。
PUT my_index
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text",
"store": true
}
}
}
}
而后再写入文档,咱们能够通过上面的语句查问到 full_name 的内容。
GET my_index/_doc/1?stored_fields=full_name
得的后果是:
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"fields" : {
"full_name" : [
"John",
"Smith"
]
}
}
如果你没有指定 store
为 true,查问的后果是这样的:
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true
}
再来看另外一个问题。把下面的 mapping 改一下,text 改为 keyword,如下:
PUT my_index
{
"mappings": {
"properties": {
"first_name": {
"type": "keyword",
"copy_to": "full_name"
},
"last_name": {
"type": "keyword",
"copy_to": "full_name"
},
"full_name": {
"type": "keyword",
"store": true
}
}
}
}
而后还是写入下面示例的两条数据。当咱们用通用的查问语句查问时发现搜寻不到后果了,这是为啥呢?我这里先给出解决方案,然而不解释原理,有趣味的能够思考下。
用上面两个查问语句都能够查问到后果,你感觉是什么起因?
GET my_index/_search
{
"query": {
"bool": {
"must": [
{"term": {
"first_name": {"value": "John"}
}},
{"term": {
"last_name": {"value": "Smith"}
}}
]
}
}
}
GET my_index/_search
{
"query": {
"terms": {
"full_name": [
"John",
"Smith"
]
}
}
}