ElasticSearch简介及常用查询语句

1 ElasticSearch简介

ElasticSearch是一个基于Lucene库的分布式全文搜索引擎。提供Restful API操作接口,很方便使用。ElasticSearch是与名为Logstash的数据收集和日志解析引擎、以及名为Kibnana的分析和可视化平台一起开发的。这三个产品被设计成一个集成解决方案,称为“Elastic Stack”;ElasticSearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。

1.1 ElasticSearch基本概念
  • Index: 相当于mysql中的数据库;
  • Type: 类似于mysql中的表,es中可以在Index中建立type(table),通过mapping进行映射;
  • Document: 由于es中存储的数据是文档型的,一条数据对应一篇文档即相当于mysql数据库中的一行数据row,一个文档可以有多个字段也就是mysql数据库一行可以有多列。
  • Mapping: 可以理解为mysql数据库中的表结构(schema);
1.2 ElasticSearch分析器
  • 分析包含下面的过程:
    (1)首先,将一块文本分成适合于倒排索引的独立的词条;
    (2)之后,将这些词条统一化为标准格式以提高它们的可搜索性;
  • 分析器执行上面的工作,实际上是将三个功能封装到一个包里:
    (1)字符过滤器: 首先,字符串按顺序通过每个字符过滤器。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and;
    (2)分词器: 其次,字符串被分词器分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条;
    (3)Token过滤器: 最后,词条按顺序通过每个token过滤器。这个过程可能会改变词条,例如最小化、删除无用词、同义处理等;
  • Elasticsearch提供了开箱即用的字符过滤器、分词器和token过滤器。这些可以组合起来形成自定义的分析器以用于不同的目的。
1.2.1 内置分析器
  • 标准分析器: 标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。它根据Unicode联盟定义的单词边界划分文本。删除绝大部分标点、将词条小写。
  • 简单分析器: 简单分析器在任何不是字母的地方分隔文本,将词条小写。
  • 空格分析器: 空格分析器在空格的地方划分文本。
  • 语言分析器: 特定语言分析器可用于很多语言。它们可以考虑指定语言的特点。比如停用词、词干提取等。
1.2.2 什么时候使用分析器
  • (1)当我们索引一个文档,它的全文域被分析成词条以用来创建 倒排索引
  • (2)当我们在全文域搜索的时候,我们需要将查询字符串通过相同的分析过程,以保证我们搜索的词条格式与索引中的词条格式一致。

2 ES常用查询语句

2.0 ES查询结果解释
  • took 字段表示该操作耗时,单位为毫秒;
  • time_out 字段表示是否超时;
  • hits 存储返回结果,下述例子返回2条结果;
  • _source 表示相关性得分;Elasticsearch权威指南:什么是相关性?
{
  "took":2,
  "timed_out":false,
  "_shards":{"total":5,"successful":5,"failed":0},
  "hits":{
    "total":2,
    "max_score":1.0,
    "hits":[
      {
        "_index":"accounts",
        "_type":"person",
        "_id":"AV3qGfrC6jMbsbXb6k1p",
        "_score":1.0,
        "_source": {
          "user": "李四",
          "title": "工程师",
          "desc": "系统管理"
        }
      },
      {
        "_index":"accounts",
        "_type":"person",
        "_id":"1",
        "_score":1.0,
        "_source": {
          "user" : "张三",
          "title" : "工程师",
          "desc" : "数据库管理,软件开发"
        }
      }
    ]
  }
}
2.1 基础查询
  • 查询mapping:GET xxxxx/_mapping
2.2 精确值查询
  • 按照poi_id精确查找:term
GET xxxxx/_search
{
  "query": {
    "term": {
      "poi_id": "xxxxx"
    }
  }
}
  • 查找结果显示部分字段:_source
GET xxxxx/_search
{
  "query": {
    "term": {
      "poi_id": "xxxxx"
    }
  },
  "_source": [ "name", "address"]
}
  • 查询多个精确值:terms
GET xxxxx/_search
{
  "query": {
    "terms": {
      "name": ["xxxxx", "xxxxx"]
    }
  }
}
2.3 布尔查询
  • 一个bool查询由三部分组成:
    (1)must 所有的语句 都必须匹配,与AND等价;
    (2)must_not 所有的语句 都不能匹配,与NOT等价;
    (3)should 一个文档不必包含brown或dog这两个词,但如果一旦包含,我们就认为它们更相关;
GET xxxxx/_search
{
  "query": {
    "bool": {
      "must":     { "match": { "title": "quick" }},
      "must_not": { "match": { "title": "lazy"  }},
      "should": [
                  { "match": { "title": "brown" }},
                  { "match": { "title": "dog"   }}
      ]
    }
  }
}
  • term查询与match查询等价转换,通过bool查询实现;
{
    "match": {
        "title": {
            "query":    "brown fox",
            "operator": "and"
        }
    }
}

{
  "bool": {
    "must": [
      { "term": { "title": "brown" }},
      { "term": { "title": "fox"   }}
    ]
  }
}
2.4 范围查询
  • 查询click_score在某个范围:range;其中gte大于等于,lt小于;
    (1)gt: > 大于(greater than)
    (2)lt: < 小于(less than)
    (3)gte: >= 大于或等于(greater than or equal to)
    (4)lte: <= 小于或等于(less than or equal to)
GET xxxxx/_search
{
  "query": {
    "range" : {
        "click_score" : {
          "gte" : xxx,  
          "lt"  : xxx
        }
    }
  }
}
2.5 基于词项与基于全文查询
  • 基于词项查询: 例如term或fuzzy这样的底层查询不需要分析阶段,它们对单个词项进行操作。记住term查询只对倒排索引的词项精确匹配,这点很重要,它不会对词的多样性进行处理(如foo或Foo)。
  • 基于全文的查询: match或query_string这样的查询是高层查询,它们了解字段映射的信息:
    (1)如果查询日期或整数字段,它们会将查询字符串分别作为日期或整数对待;
    (2)如果查询一个未分析的精确值字符串字段,它们会将整个查询字符串作为单个词项对待。
    (3)如果查询一个已分析的全文字段,它们会先将查询字符串传递到一个合适的分析器,然后生成一个供查询的词项列表。一旦组成了词项列表,这个查询会对每个词项逐一执行底层的查询,再将结果合并,然后为每个文档生成一个最终的相关度评分。
2.6 匹配查询
  • 匹配查询match是个核心查询。无论需要查询什么字段,match查询都应该会是首选的查询方式。它是一个高级全文查询,这表示它既能处理全文字段,又能处理精确字段。
  • 匹配查询控制精度:operator: or/andminimum_should_match: 75%
  • 注意: from, size:实现分页功能; sort:文档根据click_score降序排序;
GET xxxxx/_search
{
    "from": 0,
    "query": {
        "match": {
            "name": {
                "operator": "and",
                "query": "xxxxx xxxxx"
            }
        }
    },
    "size": 20,
    "sort": [
        {
            "click_score": {
                "order": "desc"
            }
        }
    ]
}
2.7 multi_match查询
  • multi_match 查询为能在多个字段上反复执行相同查询提供了一种便捷方式。multi_match关键字的作用是可以使多个字段同时匹配一个关键字,fields属性声明需要查询哪些字段。
GET xxxxx/_search
{
    "query": {
        "multi_match" : {
            "query" : "guide",
            "fields" : ["title", "authors", "summary", "publish_date", "num_reviews", "publisher"]
        }
    }
}
  • 提高某个字段的相关度,将summary这个字段的分数提高到3,增加这个字段的重要性;
GET xxxxx/_search
{
    "query": {
        "multi_match" : {
            "query" : "elasticsearch guide",
            "fields": ["title", "summary^3"]
        }
    },
    "_source": ["title", "summary", "publish_date"]
}
2.8 模糊查询
  • 模糊查询可以在matchmulti_match查询里使用,来解决用户拼写错误,模糊查询的程度声明基于原单词的莱文斯坦距离;即需要对一个字符串进行字符更改的数量,以使其与另外一个字符串相同。
  • fuzziness字段除了设置为AUTO,还可以设置为0,1,2等;
GET xxxxx/_search
{
    "query": {
        "multi_match" : {
            "query" : "comprihensiv guide",
            "fields": ["title", "summary"],
            "fuzziness": "AUTO"
        }
    },
    "_source": ["title", "summary", "publish_date"],
    "size": 1
}
2.9 短句查询
  • 短句查询(match_phrase_prefix)需要匹配所有单词才能被搜索出来,按照指定的顺序并且是连续的,默认情况下单词之间必须是连续的。但是你可以通过改写 slop 的值来声明即便两个单词之间间隔多少个单词,该文档仍被匹配出来。
GET xxxxx/_search
{
    "query": {
        "match_phrase_prefix" : {
            "summary": {
                "query": "search en",
                "slop": 3,
                "max_expansions": 10
            }
        }
    },
    "_source": [ "title", "summary", "publish_date" ]
}
2.10 地理查询
  • 限定召回数据距离在1km之内;geo_distance
  • 当我们使用布尔查询的时候,可以使用 filter 参数筛选一些结果。
GET xxxxx/_search
{
  "query":{
    "filtered": {
      "query":{
        "bool":{
          "must":[
            {
              "match":{
                "name": {
                  "query": "xxxxx xxxxx xxxxx",
                  "operator": "and"
                }
              }
            },
            {
              "match":{
                "category_code": "xxxxx"
              }
            }
          ]
        }
      },
      "filter": {
        "geo_distance": {
          "distance": "1km",
          "location": {
            "lon": xxxxx,
            "lat": xxxxx
          }
        }
      }
    }
  },
  "size": 10,
  "from": 0,
  "terminate_after": 200000
}
2.11 相关度函数
  • 有时候你可能想要根据结果的某个字段的值,来提升这条数据在这次检索中的相关度。比较典型的是你希望根据数据的被关注度来提升检索相关度。在下面的例子中,我们希望通过 reviews 的数量来提升一条文档的相关度,可以通过 field_value_factor 函数实现;
GET xxxxx/_search
{
    "query": {
        "function_score": {
            "query": {
                "multi_match" : {
                    "query" : "search engine",
                    "fields": ["title", "summary"]
                }
            },
            "field_value_factor": {
                "field" : "num_reviews",
                "modifier": "log1p",
                "factor" : 2
            }
        }
    },
    "_source": ["title", "summary", "publish_date", "num_reviews"]
}

参考资料

  • Elasticsearch: 权威指南 https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
    (1)分析与分析器:https://www.elastic.co/guide/cn/elasticsearch/guide/current/analysis-intro.html#analysis-intro
    (2)自定义分析器:https://www.elastic.co/guide/cn/elasticsearch/guide/current/custom-analyzers.html
    (3)深入搜索:https://www.elastic.co/guide/cn/elasticsearch/guide/current/search-in-depth.html
    (4)布尔过滤器:https://www.elastic.co/guide/cn/elasticsearch/guide/current/combining-filters.html
    (5)什么是相关性?:https://www.elastic.co/guide/cn/elasticsearch/guide/current/relevance-intro.html
    (6)地理距离过滤器:https://www.elastic.co/guide/cn/elasticsearch/guide/current/geo-distance.html
    (7)模糊匹配查询:https://www.elastic.co/guide/cn/elasticsearch/guide/current/fuzzy-match-query.html
    (8)排序:https://www.elastic.co/guide/cn/elasticsearch/guide/current/_Sorting.html
  • 全文搜索引擎 Elasticsearch 入门教程
    https://www.ruanyifeng.com/blog/2017/08/elasticsearch.html
  • 视频教程
    (1)搜索引擎 ElasticSearch 视频教程全集(60P)| 10 小时从入门到精通
    https://www.bilibili.com/video/av59628430/
    (2)B站讲的最好的elasticsearch教程
    https://www.bilibili.com/video/BV1kv411q7aS/?spm_id_from=333.788.videocard.0
  • [搬运] 23 个例子让你彻底搞定 Elasticsearch 的搜索查询语法
    https://ruby-china.org/topics/38431

你可能感兴趣的:(ElasticSearch简介及常用查询语句)