Elasticsearch使用要点(一)-查询

普通查询

对于文档中的text类型字段,查询:

  • match: 通过分词后,查询倒排索引进行模糊搜索.
  • match_phrase: 匹配短语, 相对于match更精确.
  • match_phrase_prefix: 前缀匹配, 用于suggestion as typing.

    从es5.0版本之前, 字符串只有string类型.es5.0之后将string类型分为text, keyword. 分别为全文字段, 精确值字段. 字符串将默认被同时映射成text和keyword类型.

查询返回部分数据:

  • 使用 _source=title,text, 来指定取回的字段.

取回多个文档:

  • 使用multi-get或者mget可以在一次请求中获取多个文档.

查询与过滤:

使用 查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分的搜索. 除此以外的情况都使用过滤(filters).

  • 过滤查询Filtering queries)只是简单的检查包含或者排除,这就使得计算起来非常快. 结果会被缓存到内存中以便快速读取.
  • 评分查询scoring queries)不仅仅要找出 匹配的文档, 还要计算每个匹配文档的相关性, 计算相关性使得它们比不评分查询费力的多.同时, 查询结果并不缓存.

查询API

match:

无论你在任何字段上进行的是全文搜索还是精确查询,match 查询是你可用的标准查询。

  • 查询使用全文搜索还是精确查询, 取决于字段的类型:

    • 如果你在一个全文字段上使用 match 查询, 查询时会现对查询参数进行分析, 然后经过倒排索引计算相关度.
    • 如果在一个精确值的字段上使用它, 例如数字、日期、布尔或者一个 not_analyzed 字符串字段, 那么它将会精确匹配给定的值.
  • 区别于filter, query对于精确值的返回结果可能不会被缓存到内存中.

multi_match:

  • multi_match 查询可以在多个字段上执行相同的 match 查询:

    1
    2
    3
    4
    5
    6
    {
    "multi_match": {
    "query": "full text search",
    "fields": [ "title", "body" ]
    }
    }

range:

  • range 查询找出那些落在指定区间内的数字或者时间:

    针对于时间来讲, es有特殊的比较语法, 可以直接在时间上操作.

    例如: now-1h代表前一个小时, 2014-01-01 00:00:00||+1M代表指定时间加一分钟.

    针对于字符串来讲, 字符串范围可以采用字典顺序排序筛选. 但是字符串比较的成本要远大于数值类型, 尤其是长字符串.

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "range": {
    "age": {
    "gte": 20,
    "lt": 30
    }
    }
    }
    • gt : 大于
    • gte : 大于等于
    • lt : 小于
    • lte : 小于等于

term:

  • term 查询对于输入的文本不分析, 被用于精确值 匹配, 相当于直接从倒排索引中查询匹配项, 然后返回匹配文档. 这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串.
  • term: 用于查找准确值单字段, 搭配filter使用.
  • terms: 用法类似与term, 区别是接受一个数组. 用于多值查找.

terms:

term 的多值匹配.

  • 如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件:

    1
    2
    3
    4
    5
    { 
    "terms": {
    "tag": [ "search", "full_text", "nosql" ]
    }
    }

exists & missing:

  • exists 查询和 missing 查询被用于查找那些指定字段中有值 或无值的文档. 类似sql中的is null, is not null:

    1
    2
    3
    4
    5
    {
    "exists": {
    "field": "title"
    }
    }
  • 存在(不存在)查询也可以指定对象类型字段. 如name是一个对象字段, 且里面包含first, last字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "exists" : { "field" : "name" }
    }

    等价于:

    {
    "bool": {
    "should": [
    { "exists": { "field": "name.first" }},
    { "exists": { "field": "name.last" }}
    ]
    }
    }