• Elasticsearch搜索与分析


    前言

    本文档主要简单记录一下在ElasticSearch中的一些搜索语句(基于阿里云ElasticSearch环境)。

    轻量搜索

    最简单的搜索应该就是一个简单的get了,如下使用get来获取数据:

    GET /index_name/_search

    返回结果:

    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 20,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "index_name",
            "_type" : "_doc",
            "_id" : "11",
            "_score" : 1.0,
            "_source" : {
              "tags" : [
                "gamegroup"
              ],
              "update_time" : 1607156354,
              "@timestamp" : "2021-02-18T03:40:01.235Z",
              "id" : 11,
              "name" : "对马岛之魂",
              "status" : 0,
              "create_time" : 1603073095,
              "@version" : "1",
            }
          },
          ···
        ]
      }
    }

    可以看到我们从index_name中获取了10条数据(默认返回10条),返回的结果在数组hits中。需要注意的是,返回结果不仅仅是告知匹配到了哪一些文档,还包含了文档本身的所有数据。

    同时,针对简单匹配的搜索,我们也可以直接使用轻量搜索,在请求路径中使用_search端点,并将查询条件赋值给参数q。如下:

    GET /index_name/_search?q=name:马岛

    返回结果:

    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 5.1153607,
        "hits" : [
          {
            "_index" : "index_name",
            "_type" : "_doc",
            "_id" : "11",
            "_score" : 5.1153607,
            "_source" : {
              "update_time" : 1607156354,
              "@timestamp" : "2021-02-18T03:40:01.235Z",
              "id" : 11,
              "name" : "对马岛之魂",
              "status": 0,
              "create_time" : 1603073095,
              "@version" : "1",
            }
          }
        ]
      }
    }

    查询表达式搜索

    按上面的查询我们可以实现最简单的搜索方式,但是在实际应用中存在很大的局限性,因为搜索业务的复杂性往往不会如此简单。所有ElasticSearch提供了一个丰富灵活的查询语句叫做查询表达式,它支持更加复杂的查询。 比如:

    GET /index_name/_search
    {
      "query": {
        "match": {
          "name": "活动"
        }
      },
      "sort": [
        {
          "id": {
            "order": "desc"
          }
        }
      ],
      "from": 0,
      "size": 10
    }

    上面的查询方式主要实现的是,查询name能与活动相匹配的数据,偏移量为0,获取10条数据,同时按照id进行排序(在没有指定排序方式的情况下,默认按照匹配分数_source排序)。

    复杂查询

    下面进行一些相比刚才要更为复杂的查询,查询index_name下的数据,要求name可以匹配关键字“马岛”,同时需要rank_num的值大于5。

    GET /index_name/_search
    {
        "query" : {
            "bool": {
                "must": {
                    "match" : {
                        "name" : "马岛" 
                    }
                },
                "filter": {
                    "range" : {
                        "rank_num" : { "gt" : 5 } 
                    }
                }
            }
        }
    }

    短语匹配

    这里简单介绍一下match与match_phrase,match匹配会将关键词进行拆分品牌,而match_phrase不会将关键词拆分。所以如果需要匹配短语的话,使用match_phrase替代match即可。

     1 GET /index_name/_search
     2 {
     3     "query" : {
     4         "bool": {
     5             "must": {
     6                 "match_phrase" : {
     7                     "name" : "马岛" 
     8                 }
     9             },
    10             "filter": {
    11                 "range" : {
    12                     "rank_num" : { "gt" : 5 } 
    13                 }
    14             }
    15         }
    16     }
    17 }

    高亮搜索(实践于官方文档有异,待确定)

    许多应用都倾向于在每个搜索结果中 高亮 部分文本片段,以便让用户知道为何该文档符合查询条件。在 Elasticsearch 中检索出高亮片段也很容易。在前面的查询中添加一个highlight字段即可。

    简单分析

    Elasticsearch 有一个功能叫聚合(aggregations),允许我们基于数据生成一些精细的分析结果。聚合与 SQL 中的 GROUP BY 类似但更强大。 如下(按照parent_id字段进行聚合):

    1 GET /index_name/_search
    2 {
    3   "aggs": {
    4     "all_interests": {
    5       "terms": { "field": "parent_id" }
    6     }
    7   }
    8 }

    返回结果:

     1 {
     2    ...
     3    "hits": { ... },
     4    "aggregations": {
     5       "all_interests": {
     6          "buckets": [
     7             {
     8               "key" : 0,
     9               "doc_count" : 66422
    10             },
    11             {
    12               "key" : -1,
    13               "doc_count" : 4716
    14             },
    15             {
    16               "key" : 27490,
    17               "doc_count" : 1684
    18             },
    19             ...
    20          ]
    21       }
    22    }
    23 }

    可以看到表中,parent_id字段每一种数据占的数量多少。 同时我们可以在查询时添加一下搜索语句:

    GET /index_name/_search
    {
      "query": {
        "match": {
          "platform": "pc"
        }
      },
      "aggs": {
        "all_interests": {
          "terms": { "field": "parent_id" }
        }
      }
    }

    返回结果:

     1 {
     2    ...
     3    "hits": { ... },
     4    "aggregations": {
     5       "all_interests": {
     6          "buckets": [
     7             {
     8               "key" : 0,
     9               "doc_count" : 52428
    10             },
    11             {
    12               "key" : -1,
    13               "doc_count" : 3494
    14             },
    15             {
    16               "key" : 27490,
    17               "doc_count" : 1684
    18             },
    19             ...
    20          ]
    21       }
    22    }
    23 }
    分级汇总

    查询方式:

     1 GET /megacorp/employee/_search
     2 {
     3     "aggs" : {
     4         "all_interests" : {
     5             "terms" : { "field" : "interests" },
     6             "aggs" : {
     7                 "avg_age" : {
     8                     "avg" : { "field" : "age" }
     9                 }
    10             }
    11         }
    12     }
    13 }

    返回结果:

    ...
      "all_interests": {
         "buckets": [
            {
               "key": "music",
               "doc_count": 2,
               "avg_age": {
                  "value": 28.5
               }
            },
            {
               "key": "forestry",
               "doc_count": 1,
               "avg_age": {
                  "value": 35
               }
            },
            {
               "key": "sports",
               "doc_count": 1,
               "avg_age": {
                  "value": 25
               }
            }
         ]
      }

    返回结果也是很好理解的,如最后一条数据表示sports的数量为1,平均年龄为25。

    作者:红雨
    出处:https://www.cnblogs.com/52why
    微信公众号: 红雨python
  • 相关阅读:
    rsync+inotify实现全网自动化数据备份-技术流ken
    高可用集群之keepalived+lvs实战-技术流ken
    高负载集群实战之lvs负载均衡-技术流ken
    实战!基于lamp安装Discuz论坛-技术流ken
    iptables实战案例详解-技术流ken
    (3)编译安装lamp三部曲之php-技术流ken
    (2)编译安装lamp三部曲之mysql-技术流ken
    (1)编译安装lamp三部曲之apache-技术流ken
    实战!基于lamp安装wordpress详解-技术流ken
    yum一键安装企业级lamp服务环境-技术流ken
  • 原文地址:https://www.cnblogs.com/52why/p/14412497.html
Copyright © 2020-2023  润新知