Use Elasticsearch in copy_to to improve search efficiency

Today in this tutorial, we'll explain how to use Elasticsearch focus on the copy to improve search efficiency. For example, in our search, we often encounter the following documents:

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

Here we can see in this document, we have such a number of fields:

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

They are very relevant. We wondered if they could be integrated into a field, so we can easily search. If we should always these three fields to search, then we can use a method should in clause clause must run bool query. This approach is too much trouble to write. Is there a better way to do that?

In fact, we can use copy_to Elasticsearch provided to improve the efficiency of our search. First, we can put our index the mapping is set to the following items (This assumes that we use is called twitter's 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
              }
            }
          }
        }
      }
    }

Here, we pay special attention to this section as follows:

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

We city, country and province three items combined into one item region, but the region does not exist in our source document's. So when we define our mapping, then, after the document is indexed, there may be a new term for our region to search.

The following data we can use to demonstrate:

    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 implementation of the above statements, it will produce our twitter index for us. At the same time we can query our mapping through the following statement:

We can see the mapping twitter of a new item called as the region. It will bring convenience for our search.

So if we want to search country: China, province: Beijing this record, we can just write the following statement on it:

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

Shown below are the results of the search:

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

So we have only one region to operate on it, or we need to search for a country, city and province, respectively.

How to view the contents of copy_to

Before the mapping, we added the following attributes of a field of region:

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

store property here is true, then we can see the document through the following command region of content:

GET twitter/_doc/1?stored_fields=region

Then the content it displays as follows:

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

If you want to learn more about Elastic Stack, please refer to the "Elasticsearch Introduction" article

Guess you like

Origin www.cnblogs.com/sanduzxcvbnm/p/12085057.html