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

561 篇文章 548 订阅 ¥79.90 ¥99.00
本文介绍了如何利用Elasticsearch的copy_to特性来提高搜索效率。通过将相关字段合并成一个新字段,例如将city, country, province合并为region,简化搜索查询,减少查询复杂性。同时,展示了如何查看copy_to后的字段内容。" 120993596,11093367,Google Earth Engine Python API快速入门与案例,"['python', 'gee', 'API', '地理空间分析', '遥感']
摘要由CSDN通过智能技术生成

在这里插入图片描述

1.概述

转载:使用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分别进行搜索。

2.如何查看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简介”

Elasticsearch的`copy_to`字段是一种用于在索引过程将字段值复制到另一个字段的机制。它允许您将一个或多个字段的内容复制到一个新的目标字段,以便在搜索和分析过程更方便地访问。 `copy_to`的原理是,在文档索引时,Elasticsearch会将指定的源字段的值复制到目标字段。这样,当执行搜索操作时,您可以直接在目标字段上执行查询,而不必考虑源字段。这对于需要在多个字段上执行相似查询的情况非常有用。 在创建索引映射时,您可以为字段指定`copy_to`属性,指定将其值复制到目标字段。例如,假设您有一个名为`title`的源字段和一个名为`combined`的目标字段,您可以将`title`字段的内容复制到`combined`字段: ``` PUT my_index { "mappings": { "properties": { "title": { "type": "text", "copy_to": "combined" }, "combined": { "type": "text" } } } } ``` 当您索引一个文档时,`title`字段的值将自动复制到`combined`字段。这样,您就可以在搜索时直接对`combined`字段执行查询操作,而不必考虑`title`字段。 请注意,`copy_to`并不是实时的操作,它只在文档索引时生效。因此,对源字段进行更新不会自动触发目标字段的更新。如果您对源字段进行了更改,您需要手动重新索引文档以确保目标字段的值也得到更新。 希望这个解释对您有所帮助!如果您还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值