带你读《Elastic Stack 实战手册》之38:——3.4.2.19.copy_to

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 带你读《Elastic Stack 实战手册》之38:——3.4.2.19.copy_to

3.4.2.19.copy_to


创作人:章海怒

审稿人:欧阳楚才

 

在写入数据时对写入的内容进行拼贴,组合成一个全新的数据;也就是说固定的数据的拼接可以在 ES 中先完成,而不需要在查询数据时针对查询做繁杂的拼接。

 

关键词:copy_to

 

copy_to 参数允许将多个字段的值复制到一个单独的字段中,然后可以将其作为单个字段进行查询。

 

使用场景:copy_to 的一个常见用法就是用来减少搜索的字段数来提升搜索的效率;查询的字段越多,理论上 ES 的返回就越慢。多字段查询的时候,一种常见的性能优化方式是通过 copy_to 将多个查询字段的值合并为1个字段(数据的简单拼贴),通过合并后的字段进行查询,这样可以有效避免 multi_match 的使用,并且可以使得效率提高。

 

例如:

{
    "user": "双榆树-张三",
    "message": "今儿天气不错啊,出去转转去",
    "uid": 2,
    "age": 20,
    "city": "北京",
    "province": "北京",
    "country": "中国",
    "address": "中国北京市海淀区",
    "location": {
        "lat": "39.970718",
           "lon": "116.325747"
    }
}

在这里,我们可以看到在这个文档中,有这样的几个相关字段:city、province、country ,如果想放在一起搜索,一种方法我们可以在 must 子句中使用 should 子句查询。这种方法写起来比较麻烦并且性能比较低。这个时候,我们就可以考虑用 copy_to 将3个字段糅合成一个字段来搜索

 

例如:


PUT twitter
{
    "mappings": {
        "properties": {
            "address": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "age": {
                "type": "long"
            },
            "city": {
                "type": "keyword",
                "copy_to": "region"
            },
            "country": {
                "type": "keyword",
                "copy_to": "region"
            },
            "province": {
                "type": "keyword",
                "copy_to": "region"
            },
            "region": {
                "type": "text",
                "store": true
            },
            "location": {
                "type": "geo_point"
            },
            "message": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "uid": {
                "type": "long"
            },
            "user": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            }
        }
    }
}

我们通过 mapping 时声明 copy_to 的指定,把 city、 country 及 province 三个字段合并成为一个字段 region,但是这个 region 并不存在于我们文档的 source 里

 

我们录入一些样例数据:


POST _bulk
{ "index" : { "_index" : "twitter", "_id": 1} }
{"user":"双榆树-张三","message":"今儿天气不错啊,出去转转去","uid":2,"age":20,"city":"北京","province":"北京","country":"中国","address":"中国北京市海淀区","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"东城区-老刘","message":"出发,下一站云南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区台基厂三条3号","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"东城区-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝阳区-老贾","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区建国门","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝阳区-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区国贸","location":{"lat":"39.918256","lon":"116.467910"}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹桥-老吴","message":"好友来了都今天我生日,好友来了,什么 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中国","address":"中国上海市闵行区","location":{"lat":"31.175927","lon":"121.383328"}}

假如我们想搜索 country : 中国,province : 北京 这样的记录,我们可以只写如下的一条语句就可以了


GET twitter/_search
{
    "query": {
        "match": {
            "region": {
                "query": "中国 北京",
                "minimum_should_match": 4
            }
        }
    }
}

如果想查看 copy_to 的内容,就需要如例子中,显性的声明 region 这个字段 "store": true

声明以后就可以通过:

 

GET twitter/_doc/1?stored_fields=region

来查看对应region的内容,以上查询可以返回结果:

{
    "_index": "twitter",
    "_type": "_doc",
    "_id": "1",
"_version": 1,
  "_seq_no": 0,
    "_primary_term": 1,
    "found": true,
    "fields": {
        "region": [
            "北京",
            "北京",
            "中国"
        ]
    }
}


小贴士:

 

1、copy_to 是值拷贝,也就是说拷贝之后 city ,provice 还是可以独立用于查询(与传统值拷贝不同的是,ES 更新时先查询出原来的文档,然后插入一条新文档,标记删除旧文档,所以copy_to 的字段在源字段更新时,会同时更新)。

2、copy_to 不可以嵌套使用。

3、可以拷贝至多个字段例如 "copy_to": [ "field_1", "field_2" ]。

4、copy_to 的字段本身包含类型的声明,支持不同类型的数据 copy_to 到同一字段,会有一次类型的转换。

5、copy_to 实际 copy 发生在数据写入时,会直接形成一个新的字段,所以 copy_to 实际会占用集群的磁盘、物理资源等。

 

本文部分内容参考自CSDN——Elastic 中国社区官方博客

 

 

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
自然语言处理 索引
带你读《Elastic Stack 实战手册》之33:——3.4.2.17.2.Schemaless(上)
带你读《Elastic Stack 实战手册》之33:——3.4.2.17.2.Schemaless(上)
106 0
|
存储 运维 监控
带你读《Elastic Stack 实战手册》之2:——二、导读(下)
带你读《Elastic Stack 实战手册》之2:——二、导读(下)
259 0
|
SQL 自然语言处理 监控
带你读《Elastic Stack 实战手册》之2:——二、导读(上)
带你读《Elastic Stack 实战手册》之2:——二、导读(上)
333 0
|
JSON Java 数据格式
带你读《Elastic Stack 实战手册》之33:——3.4.2.17.2.Schemaless(下)
带你读《Elastic Stack 实战手册》之33:——3.4.2.17.2.Schemaless(下)
100 0
|
索引
带你读《Elastic Stack 实战手册》之56:——3.5.15.Snapshot (中)
带你读《Elastic Stack 实战手册》之56:——3.5.15.Snapshot (中)
114 0
|
存储 分布式计算 监控
带你读《Elastic Stack 实战手册》之56:——3.5.15.Snapshot (下)
带你读《Elastic Stack 实战手册》之56:——3.5.15.Snapshot (下)
135 0
|
存储 API
带你读《Elastic Stack 实战手册》之56:——3.5.15.Snapshot (上)
带你读《Elastic Stack 实战手册》之56:——3.5.15.Snapshot (上)
132 0
|
存储 资源调度 NoSQL
带你读《Elastic Stack 实战手册》之45:——3.5.4.Graph (上)
带你读《Elastic Stack 实战手册》之45:——3.5.4.Graph (上)
124 0
|
数据可视化 NoSQL API
带你读《Elastic Stack 实战手册》之45:——3.5.4.Graph (下)
带你读《Elastic Stack 实战手册》之45:——3.5.4.Graph (下)
138 0
|
存储 JSON 数据库
带你读《Elastic Stack 实战手册》之17:—— 3.4.2.2.理解mapping(上)
带你读《Elastic Stack 实战手册》之17:—— 3.4.2.2.理解mapping(上)

热门文章

最新文章