使用Elasticsearch中的copy_to来提高搜索效率

在今天的这个教程中,我们来着重讲解一下如何使用Elasticsearch中的copy来提高搜索的效率。比如在我们的搜索中,经常我们会遇到如下的文档:

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

在这里,我们可以看到在这个文档中,我们有这样的几个字段:

     "city" : "北京",
     "province" : "北京",
     "country" : "中国",

它们是非常相关的。我们在想是不是可以把它们综合成一个字段,这样可以方便我们的搜索。假如我们要经常对这三个字段进行搜索,那么一种方法我们可以在must子句中使用should子句运行bool查询。这种方法写起来比较麻烦。有没有一种更好的方法呢?

我们其实可以使用Elasticsearch所提供的copy_to来提高我们的搜索效率。我们可以首先把我们的index的mapping设置成如下的项(这里假设我们使用的是一个叫做twitter的index)。

    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
              }
            }
          }
        }
      }
    }

在这里,我们特别注意如下的这个部分:

        "city": {
          "type": "keyword",
          "copy_to": "region"
        },
        "country": {
          "type": "keyword",
          "copy_to": "region"
        },
        "province": {
          "type": "keyword",
          "copy_to": "region"
        },
        "region": {
          "type": "text"
        }

我们把city, country及province三个项合并成为一个项region,但是这个region并不存在于我们文档的source里。当我们这么定义我们的mapping的话,在文档被索引之后,有一个新的region项可以供我们进行搜索。

我们可以采用如下的数据来进行展示:

    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"}}

在Kibnana中执行上面的语句,它将为我们生产我们的twitter索引。同时我们可以通过如下的语句来查询我们的mapping:

我们可以看到twitter的mapping中有一个新的被称作为region的项。它将为我们的搜索带来方便。

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

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

下面显示的是搜索的结果:

    {
      "took" : 0,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 5,
          "relation" : "eq"
        },
        "max_score" : 0.8114117,
        "hits" : [
          {
            "_index" : "twitter",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 0.8114117,
            "_source" : {
              "user" : "双榆树-张三",
              "message" : "今儿天气不错啊,出去转转去",
              "uid" : 2,
              "age" : 20,
              "city" : "北京",
              "province" : "北京",
              "country" : "中国",
              "address" : "中国北京市海淀区",
              "location" : {
                "lat" : "39.970718",
                "lon" : "116.325747"
              }
            }
          },
          {
            "_index" : "twitter",
            "_type" : "_doc",
            "_id" : "2",
            "_score" : 0.8114117,
            "_source" : {
              "user" : "东城区-老刘",
              "message" : "出发,下一站云南!",
              "uid" : 3,
              "age" : 30,
              "city" : "北京",
              "province" : "北京",
              "country" : "中国",
              "address" : "中国北京市东城区台基厂三条3号",
              "location" : {
                "lat" : "39.904313",
                "lon" : "116.412754"
              }
            }
          },
          {
            "_index" : "twitter",
            "_type" : "_doc",
            "_id" : "3",
            "_score" : 0.8114117,
            "_source" : {
              "user" : "东城区-李四",
              "message" : "happy birthday!",
              "uid" : 4,
              "age" : 30,
              "city" : "北京",
              "province" : "北京",
              "country" : "中国",
              "address" : "中国北京市东城区",
              "location" : {
                "lat" : "39.893801",
                "lon" : "116.408986"
              }
            }
          },
          {
            "_index" : "twitter",
            "_type" : "_doc",
            "_id" : "4",
            "_score" : 0.8114117,
            "_source" : {
              "user" : "朝阳区-老贾",
              "message" : "123,gogogo",
              "uid" : 5,
              "age" : 35,
              "city" : "北京",
              "province" : "北京",
              "country" : "中国",
              "address" : "中国北京市朝阳区建国门",
              "location" : {
                "lat" : "39.718256",
                "lon" : "116.367910"
              }
            }
          },
          {
            "_index" : "twitter",
            "_type" : "_doc",
            "_id" : "5",
            "_score" : 0.8114117,
            "_source" : {
              "user" : "朝阳区-老王",
              "message" : "Happy BirthDay My Friend!",
              "uid" : 6,
              "age" : 50,
              "city" : "北京",
              "province" : "北京",
              "country" : "中国",
              "address" : "中国北京市朝阳区国贸",
              "location" : {
                "lat" : "39.918256",
                "lon" : "116.467910"
              }
            }
          }
        ]
      }
    }

这样我们只对一个region进行操作就可以了,否则我们需要针对country, city及province分别进行搜索。

如何查看copy_to的内容

在之前的mapping中,我们对region字段加入了如下的一个属性:

          "region": {
            "type": "text",
            "store": true
          }

这里的store属性为true,那么我们可以通过如下的命令来查看文档的region的内容:

GET twitter/_doc/1?stored_fields=region

那么它显示的内容如下:

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

如果你想了解更多关于Elastic Stack,请参阅文章“Elasticsearch简介”

原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/12085057.html

时间: 2024-08-26 13:18:06

使用Elasticsearch中的copy_to来提高搜索效率的相关文章

iOS开发中使用宏定义提高开发效率

iOS开发中使用宏定义提高开发效率 (2013-07-10 10:47:33) 转载▼ iOS开发中,巧妙的使用宏定义,可以提高开发效率,本篇简单介绍一下宏的定义,设置,应用,并在未来实践中不断追加一些常用的宏定义. 调试Log iPhone应用程序开发调试的时候,在代码中加入NSLog的暴力调试方法是很频繁的,但是在release的时候要删除这些调试代码,那工作量是烦躁,这样的情况下,试用宏就会显得非常的方便. 看下面的例子: #ifdef DEBUG #define LOG(...) NSL

数据库查寻中,这样去提高查询效率

1)数据库设计方面:         a. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引.         b. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0 c. 并不是所

Outlook2013中三个有助于提高工作效率的使用技巧

一.搜索文件夹 在Outlook中除了预定义的像收件箱.已发送邮件等文件夹外,我们还可以通过设定搜索条件添加自定义文件夹,如下图所示, 右键点击搜索文件→新建搜索文件夹 预定义搜索文件夹 打开新建搜索文件夹对话框,这里已经预设几个搜索条件,例如未读邮件按.含有附件的邮件.重要邮件等等,选择一个后点击确定就创建好搜索文件夹了. 继续阅读>>

union all 取代 select中的case when 提高查询效率

首先union all不是适用于所有情况,其次,case when的可读性肯定要强.所以在不是特别在意性能的情况下, 可以考虑用case when. 再者,不是所有情况下的union all都要比case when好,当然理论上来说标题给的只是一个建议,理论上它是要比 case when要快. 因为case when是需要逐条分析查询结果的,而转换成union all后,分析这一步就可以省掉了.数据量越大,优势 越明显.

倍数提高工作效率的 Android Studio 奇技

来源:JeremyHe 链接:http://zlv.me/posts/2015/07/13/14_android-studio-tips/ 这是从Philippe Breault的系列文章<Android Studio Tips Of the Day>中提取出来的自认为精华的部分.这些技巧在实际应用中能够非常大的提高工作效率. 关于快捷键 The File Structure Popup ctrl+f12 此快捷键可以调出当前文件的大纲,并通过模糊匹配快速跳转至指定的方法.勾选上“show a

ElasticSearch中的一些概念

索引词(term) 在elasticsearch中索引词(term)是一个能够被索引的精确值.foo,Foo Foo几个单词是不相同的索引词.索引词(term)是可以通过term查询进行准确的搜索. 文本(text) 文本是一段普通的非结构化文字,通常,文本会被分析称一个个的索引词,存储在elasticsearch的索引库中,为了让文本能够进行搜索,文本字段需要事先进行分析:当对文本中的关键词进行查询的时候,搜索引擎应该根据搜索条件搜索出原文本. 分析(analysis) 分析是将文本转换为索引

AppStore海外优化 如何提高搜索排名及应用好评

ASO流量在海外的主要来源是App Store和社交网站: 社交网站:Facebook.Twitter为主 App Store:精品推荐.榜单.搜索:今天就给大家讲讲APP关键字优化以及如何提高搜索排名: 关键字ASO有两个部分:关键字的覆盖率并且让这些词的搜索结果排在前面.有效关键词的覆盖就是通过优化副标题和100个关键字来实现. 副标题里面的词有着很高的权重,所以我们要将本行业最难优化的词语放在里面,为了躲避过苹果的审核可以连成通顺句子放在你的品牌名后面.副标题也没必要非常频繁 的更换,频繁

善用VS中的Code Snippet来提高开发效率

http://www.cnblogs.com/anderslly/archive/2009/02/16/vs2008-code-snippets.html http://www.cnblogs.com/jaic-xiao/archive/2008/10/14/Jie_Shao_Net_Gong_Ju_Code_Snippet_Yu_Sql_Server_2008_Gong_Ju_SSMS_Tools_Pack.html 前言 在谈谈VS中的模板中,我介绍了如何创建项目/项模板,这种方式可以在创建

elasticsearch中的几个概念总结

1.Geo spatial search : 地理空间搜索,可以在搜索查询中指定的某一距离内查找所要的内容,也能够返回以当前为圆心,逐渐增加圆的半径,直到找到所匹配到的内容. 参考:http://www.forwardsearch.dk/en/ForwardSearch/InDepth/Geo-spatial%20search.aspx 2.Multi tenancy:多租户 (1)Multi-tenancy means that different customers can have dif