Elasticsearch(2.x)权威指南

注意文档中使用的Elasticsearch版本为2.x版本,此次阅读仅是为了较系统的对Elasticsearch进行学习。

后续再计划对最新版本的文档进行研读;

本地环境使用的Elasticseach版本为6.8,所在在阅读过程中会对兼容性问题进行解决;

Elasticsearch权威指南

1、索引员工文档

其中megacorp为索引,employee为类型

curl -X PUT "localhost:9200/megacorp/employee/1?pretty" -H 'Content-Type: application/json' -d'
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
'
curl -X PUT "localhost:9200/megacorp/employee/2?pretty" -H 'Content-Type: application/json' -d'
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
'
curl -X PUT "localhost:9200/megacorp/employee/3?pretty" -H 'Content-Type: application/json' -d'
{
    "first_name" :  "Douglas",
    "last_name" :   "Fir",
    "age" :         35,
    "about":        "I like to build cabinets",
    "interests":  [ "forestry" ]
}
'

2、检索文档

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/1?pretty"
  • Response
  {"_index":"megacorp","_type":"employee","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}}

3、轻量搜索

3.1、搜索所有数据

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty"
  • Response
  {"took":3,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":1.0,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":1.0,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}},{"_index":"megacorp","_type":"employee","_id":"3","_score":1.0,"_source":{"first_name":"Douglas","last_name":"Fir","age":35,"about":"I like to build cabinets","interests":["forestry"]}}]}}

### 3.2、使用q参数赋值的方式进行搜索

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?q=last_name:Smith+first_name:John&pretty"
  • Response
  {
    "took" : 7,
    "timed_out" : false,
    "_shards" : {
      "total" : 21,
      "successful" : 21,
      "skipped" : 0,
      "failed" : 0
    },
    "hits" : {
      "total" : 2,
      "max_score" : 0.5753642,
      "hits" : [
        {
          "_index" : "megacorp",
          "_type" : "employee",
          "_id" : "1",
          "_score" : 0.5753642,
          "_source" : {
            "first_name" : "John",
            "last_name" : "Smith",
            "age" : 25,
            "about" : "I love to go rock climbing",
            "interests" : [
              "sports",
              "music"
            ]
          }
        },
        {
          "_index" : "megacorp",
          "_type" : "employee",
          "_id" : "2",
          "_score" : 0.2876821,
          "_source" : {
            "first_name" : "Jane",
            "last_name" : "Smith",
            "age" : 32,
            "about" : "I like to collect rock albums",
            "interests" : [
              "music"
            ]
          }
        }
      ]
    }
  }

4、使用查询

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
      "query" : {
          "match" : {
              "last_name" : "Smith"
          }
      }
  }
  '
  • Response
  {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":0.2876821,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":0.2876821,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":0.2876821,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}}]}}

5、使用过滤器

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
      "query" : {
          "bool": {
              "must": {
                  "match" : {
                      "last_name" : "smith" 
                  }
              },
              "filter": {
                  "range" : {
                      "age" : { "gt" : 30 } 
                  }
              }
          }
      }
  }
  '

gt:>;lt:<;gte:>=;lte:<=;

  • Response
  {"took":6,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":0.2876821,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}}]}}

6、全文索引(模糊)

搜索所有喜欢rock climbing的员工,而搜索结果有Jane Smith,他是喜欢rock albums,只是提到了rock也被检索出来了,但是搜索结果中的_score得分较低;

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
      "query" : {
          "match" : {
              "about" : "rock climbing"
          }
      }
  }
  '
  • Response
  {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":0.5753642,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.5753642,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}},{"_index":"megacorp","_type":"employee","_id":"2","_score":0.2876821,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}}]}}

7、短语搜索(精确匹配一系列的单词或者短语)

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
      "query" : {
          "match_phrase" : {
              "about" : "rock climbing"
          }
      }
  }
  '
  • Response
  {"took":14,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.5753642,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.5753642,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}}]}}

8、高亮搜索

每个搜索结果中高亮部分文本片段,以便让用户知道为何该文档符合查询条件

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
      "query" : {
          "match" : {
              "about" : "rock climbing"
          }
      },
      "highlight": {
          "fields" : {
              "about" : {}
          }
      }
  }
  '
  • Response
  {"took":5,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":0.5753642,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.5753642,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]},"highlight":{"about":["I love to go <em>rock</em> <em>climbing</em>"]}},{"_index":"megacorp","_type":"employee","_id":"2","_score":0.2876821,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]},"highlight":{"about":["I like to collect <em>rock</em> albums"]}}]}}

9、分析

聚合功能(aggregations),允许我们急于数据生成一些精细的分析结果。

9.1、举个例子,挖掘员工中最受欢迎的兴趣爱好

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
    "aggs": {
      "all_interests": {
        "terms": { "field": "interests" }
      }
    }
  }
  '
  • 异常情况处理
  • 上述curl请求之后,返回报错结果如下:
  {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"megacorp","node":"BN1eWLRDQneT3Zqr4leglw","reason":{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."}}],"caused_by":{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.","caused_by":{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."}}},"status":400}

Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.翻译为默认情况下,文本字段禁用Fielddata。设置fielddata=true对[兴趣],以便通过反转反向索引在内存中加载fielddata。请注意,这可能会使用大量内存。或者使用关键字字段

  • Elasticsearch 5.x版本以后,对排序和聚合等操作,用单独的数据结构(fielddata)缓存到内存里了,默认是不开启的需要单独开启参考elastic.co文档中fielddata
  • 解决方法 curl -X PUT "localhost:9200/megacorp/_mapping/employee/" -H 'Content-Type: application/json' -d' { "properties": { "interests": { "type":"text", "fielddata": true } } } '
  • Response
  {"took":2,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":1.0,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":1.0,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}},{"_index":"megacorp","_type":"employee","_id":"3","_score":1.0,"_source":{"first_name":"Douglas","last_name":"Fir","age":35,"about":"I like to build cabinets","interests":["forestry"]}}]},"aggregations":{"all_interests":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"music","doc_count":2},{"key":"forestry","doc_count":1},{"key":"sports","doc_count":1}]}}}

9.2、举个例子,想知道叫Smith的员工中最受欢迎的兴趣爱好

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
    "query": {
      "match": {
        "last_name": "smith"
      }
    },
    "aggs": {
      "all_interests": {
        "terms": {
          "field": "interests"
        }
      }
    }
  }
  '
  • Response
  {"took":2,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":0.2876821,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":0.2876821,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":0.2876821,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}}]},"aggregations":{"all_interests":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"music","doc_count":2},{"key":"sports","doc_count":1}]}}}

9.3、聚合支持分级汇总,查询特定兴趣爱好员工的平均年龄

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
  {
      "aggs" : {
          "all_interests" : {
              "terms" : { "field" : "interests" },
              "aggs" : {
                  "avg_age" : {
                      "avg" : { "field" : "age" }
                  }
              }
          }
      }
  }
  '
  • Response
  {"took":22,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":1.0,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":1.0,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}},{"_index":"megacorp","_type":"employee","_id":"3","_score":1.0,"_source":{"first_name":"Douglas","last_name":"Fir","age":35,"about":"I like to build cabinets","interests":["forestry"]}}]},"aggregations":{"all_interests":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"music","doc_count":2,"avg_age":{"value":28.5}},{"key":"forestry","doc_count":1,"avg_age":{"value":35.0}},{"key":"sports","doc_count":1,"avg_age":{"value":25.0}}]}}}

10、查看Elasticsearch集群健康情况

  • cURL
  curl -X GET "localhost:9200/_cluster/health?pretty"
  • Response
  {
    "cluster_name": "elasticsearch",
    "status": "yellow",
    "timed_out": false,
    "number_of_nodes": 1,
    "number_of_data_nodes": 1,
    "active_primary_shards": 27,
    "active_shards": 27,
    "relocating_shards": 0,
    "initializing_shards": 0,
    "unassigned_shards": 23,
    "delayed_unassigned_shards": 0,
    "number_of_pending_tasks": 0,
    "number_of_in_flight_fetch": 0,
    "task_max_waiting_in_queue_millis": 0,
    "active_shards_percent_as_number": 54.0
  }

green:所有的主分片和副本都正常运行;yellow:所有的主分片都正常运行,但不是所有的副本分片都正常运行;red:有主分片没能正常运行;

11、返回文档的部分

11.1、指定返回ageinterests两个部分的数据

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/1?_source=age,interests&pretty"
  • Response
  {"_index":"megacorp","_type":"employee","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"interests":["sports","music"],"age":25}}

11.2、只返回文档部分

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/1/_source"
  • Response
  {"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"]}

12、文档的部分更新

  • cURL
  curl -X POST "localhost:9200/megacorp/employee/1/_update" -H 'Content-Type: application/json' -d'
  {
     "doc" : {
        "tags" : [ "testing" ],
        "views": 0
     }
  }
  '
  • Respone
  {"_index":"megacorp","_type":"employee","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":1,"_primary_term":1}

13、使用脚本部分更新文档

数组增加元素{"script":{"inline":"ctx._source.tags.add(params.tag)","params":{"tag":"search"}}}或者减少元素{"script":{"inline":"ctx._source.tags.remove(ctx._source.tags.indexOf(params.tag))","params":{"tag":"search"}}}

该文档中以下的方式已经不兼容

{
   "script" : "ctx._source.tags+=new_tag",
   "params" : {
      "new_tag" : "search"
   }
}
  • cURL
  curl -X POST "localhost:9200/megacorp/employee/1/_update" -H 'Content-Type: application/json' -d'
  {
     "script" : "ctx._source.views+=1"
  }
  '
  • cURL(数组增加元素)
  curl -X POST "localhost:9200/megacorp/employee/1/_update" -H 'Content-Type: application/json' -d'
  {"script":{"inline":"ctx._source.tags.add(params.tag)","params":{"tag":"search"}}}
  '

14、取回多个文档

14.1、可以将index和type放在body体传入,此时可以分别传入不同的index和type

  • cURL
  curl -X GET "localhost:9200/_mget?pretty" -H 'Content-Type: application/json' -d'
  {
     "docs" : [
        {
           "_index" : "megacorp",
           "_type" :  "employee",
           "_id" :    1
        },
        {
           "_index" : "megacorp",
           "_type" :  "employee",
           "_id" :    2
        }
     ]
  }
  '
  • Response
  {"docs":[{"_index":"megacorp","_type":"employee","_id":"1","_version":10,"_seq_no":9,"_primary_term":1,"found":true,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]}},{"_index":"megacorp","_type":"employee","_id":"2","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}}]}

14.2、在pathvalue中确定index和type

  • cURL
  curl -X GET "localhost:9200/megacorp/employee/_mget?pretty" -H 'Content-Type: application/json' -d'

  {
    "ids":["2","1"]
  }
  '
  • Response
  {"docs":[{"_index":"megacorp","_type":"employee","_id":"2","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_version":10,"_seq_no":9,"_primary_term":1,"found":true,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]}}]}

15、分页搜索

  • cURL

每页展示5条结果,可以用下面的方式请求得到1到3页的结果

  curl -X GET "localhost:9200/_search?size=5&pretty"
  curl -X GET "localhost:9200/_search?size=5&from=5&pretty"
  curl -X GET "localhost:9200/_search?size=5&from=10&pretty"

16、多索引和多类型

  • cURL
  /_search
  在所有的索引中搜索所有的类型
   /gb/_search
  在 gb 索引中搜索所有的类型
   /gb,us/_search
  在 gb 和 us 索引中搜索所有的文档
   /g*,u*/_search
  在任何以 g 或者 u 开头的索引中搜索所有的类型
   /gb/user/_search
  在 gb 索引中搜索 user 类型
   /gb,us/user,tweet/_search
  在 gb 和 us 索引中搜索 user 和 tweet 类型
   /_all/user,tweet/_search
  在所有的索引中搜索 user 和 tweet 类型

17、查看映射

  • cURL
  GET /megacorp/_mapping/employee
  • Response
  {"megacorp":{"mappings":{"employee":{"properties":{"about":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"age":{"type":"long"},"first_name":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"interests":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}},"fielddata":true},"last_name":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"tags":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"views":{"type":"long"}}}}}}

18、创建map中使用到的indexanalyzer

  • cURL
  curl -X PUT "localhost:9200/gb" -H 'Content-Type: application/json' -d'
  {
    "mappings": {
      "tweet" : {
        "properties" : {
          "tweet" : {
            "type" :    "text",
            "analyzer": "english"
          },
          "date" : {
            "type" :   "date"
          },
          "name" : {
            "type" : "text",
            "index": false
          },
          "user_id" : {
            "type" :   "long"
          }
        }
      }
    }
  }
  '

6.8版本已经取消type为string的类型,以及index仅可赋值true或者false(而不是analyzed, not_analyzed,no)

19、内部对象的映射

  • cURL
  POST {{host}}/tweet/_doc/_create
  Content-Type: application/json

  {
      "tweet":"Elasticsearch is very flexible",
      "user":{
          "id":"@johnsmith",
          "gender":"male",
          "age":26,
          "name":{
              "full":"John Smith",
              "first":"John",
              "last":"Smith"
          }
      }
  }
  • 此时tweet._doc的映射关系如下:
  {"tweet":{"mappings":{"_doc":{"properties":{"tweet":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"user":{"properties":{"age":{"type":"long"},"gender":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"id":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"name":{"properties":{"first":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"full":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"last":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}}}}}}}
  • 内部对象进行索引,将文档转化为以下的格式,
  {
      "tweet":            [elasticsearch, flexible, very],
      "user.id":          [@johnsmith],
      "user.gender":      [male],
      "user.age":         [26],
      "user.name.full":   [john, smith],
      "user.name.first":  [john],
      "user.name.last":   [smith]
  }
  • 内部对象数组
  {
      "followers": [
          { "age": 35, "name": "Mary White"},
          { "age": 26, "name": "Alex Jones"},
          { "age": 19, "name": "Lisa Smith"}
      ]
  }

进行扁平化处理

  {
      "followers.age":[19, 26, 35],
      "followers.name":["alex", "jones", "lisa", "smith", "mary", "white"]
  }

扁平化处理之后,便将”age”: 35 <-> “name”: “Mary White”的相关性丢失了,此时的数据结构仅可以搜索出是否有一个26岁的追随者?而如何搜索出是否有一个26岁,名字叫做Alex Jones 的追随者?

解决这个问题需要引入嵌套对象(Nested)。

20、查询表达式

20.1、简单查询

  • cURL
  GET localhost:9200/megacorp/employee/_search?q=john

  GET localhost:9200/megacorp/employee/_search?q=last_name:Smith+first_name:John

20.2、空查询

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "match_all":{}
      }
  }



  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {}

空查询等同上面的match_all

20.3 match查询

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "match":{
              "about":"rock"
          }
      }
  }

20.4、multi_match 查询

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

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "multi_match":{
              "query":"rock search",
              "fields":[
                  "tags",
                  "about"
              ]
          }
      }
  }

20.5、range查询

range 查询找出那些落在指定区间内的数字或者时间;gt:>;gte:>=;lt:<;lte:<=;

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "range":{
              "age":{
                  "gte":20,
                  "lt":30
              }
          }
      }
  }

20.5、term查询

term 查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者index设置为false的text(如果index设置为true的text无法做到精确值匹配)

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "term":{
              "age":25
          }
      }
  }

20.6、terms查询

terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "terms":{
              "interests":["sport","forestry"]
          }
      }
  }

term 查询一样,terms 查询对于输入的文本不分析。它查询那些精确匹配的值(包括在大小写、重音、空格等方面的差异)

20.7、exists查询和missing查询

exists 查询和 missing 查询被用于查找那些指定字段中有值 (exists) 或无值 (missing) 的文档。这与SQL中的 IS_NULL (missing) 和 NOT IS_NULL (exists) 在本质上具有共性

  • existscURL

megacorp.employee所有doc中views not is null的doc

  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "exists":{
              "field":"views"
          }
      }
  }
  • missingcURL

missing 已经从 ES 5 版本移除,使用exists查询取反的方式

  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query": {
          "bool": {
              "must_not": {
                  "exists": {
                      "field": "views"
                  }
              }
          }
      }
  }

30、组合多查询

30.1、bool混合布尔查询

现实的查询需求从来都没有那么简单;它们需要在多个字段上查询多种多样的文本,并且根据一系列的标准来过滤。为了构建类似的高级查询,你需要一种能够将多查询组合成单一查询的查询方法。

你可以用 bool 查询来实现你的需求。这种查询将多查询组合在一起,成为用户自己想要的布尔查询

Occur的对照表(2.x)

OccurDescription
must文档 必须 匹配这些条件才能被包含进来
must_not文档 必须不 匹配这些条件才能被包含进来
should如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分
filter必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档

Occur的对照表(6.8)

OccurDescription
mustThe clause (query) must appear in matching documents and will contribute to the score.
must_notThe clause (query) must not appear in the matching documents. Clauses are executed in filter context meaning that scoring is ignored and clauses are considered for caching. Because scoring is ignored, a score of 0 for all documents is returned.
shouldThe clause (query) should appear in the matching document. If the bool query is in a query context and has a must or filter clause then a document will match the bool query even if none of the should queries match. In this case these clauses are only used to influence the score. If the bool query is in a filter context or has neither must or filter then at least one of the should queries must match a document for it to match the bool query. This behavior may be explicitly controlled by setting the minimum_should_match parameter.
filterThe clause (query) must appear in matching documents. However unlike must the score of the query will be ignored. Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.
  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query": {
          "bool": {
              "must": {"match":{"about":"rock"}},
              "must_not":{"match":{"age":32}},
              "filter":[
                  {"range":{"views":{"lte":1}}}
              ]
          }
      }
  }
  • Response
  {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.2876821,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]}}]}}

30.2、constant_score查询

将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下;可以使用它来取代只有 filter 语句的 bool 查询。在性能上是完全相同的,但对于提高查询简洁性和清晰度有很大帮助;

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query": {
          "bool": {
              "filter":[
                  {"terms":{"interests":["music"]}}
              ]
          }
      }
  }
  • Response
  {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":0.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":0.0,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":0.0,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]}}]}}

由于filter不对评分有贡献,通过bool查询,_score均为0;

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query": {
          "constant_score": {
              "filter":{
                  "terms":{
                      "interests":["music"]
                  }
              }
          }
      }
  }
  • Response
  {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":1.0,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":1.0,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]}}]}}

31、排序

31.1、按照字段的值进行排序

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query": {
          "bool":{
              "must":{
                  "match_all":{}
              }
          }
      },
      "sort":{
          "age":{"order":"desc"}
      }
  }
  • Response
  {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":null,"hits":[{"_index":"megacorp","_type":"employee","_id":"3","_score":null,"_source":{"first_name":"Douglas","last_name":"Fir","age":35,"about":"I like to build cabinets","interests":["forestry"]},"sort":[35]},{"_index":"megacorp","_type":"employee","_id":"2","_score":null,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]},"sort":[32]},{"_index":"megacorp","_type":"employee","_id":"1","_score":null,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]},"sort":[25]}]}}

默认排序是通过_score,如果指定排序,则_score将不被计算;

如果无论如何都需要计算出_score,可以对track_scores参数设置为true

31.2、多级排序

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query": {
          "bool":{
              "must":{
                  "match_all":{}
              }
          }
      },
      "sort":[
          {"age":{"order":"desc"}},
          {"views":{"order":"asc"}}
      ]
  }
  • Response
  {"took":2,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":null,"hits":[{"_index":"megacorp","_type":"employee","_id":"3","_score":null,"_source":{"first_name":"Douglas","last_name":"Fir","age":35,"about":"I like to build cabinets","interests":["forestry"]},"sort":[35,9223372036854775807]},{"_index":"megacorp","_type":"employee","_id":"2","_score":null,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]},"sort":[32,9223372036854775807]},{"_index":"megacorp","_type":"employee","_id":"1","_score":null,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]},"sort":[25,1]}]}}

32、查找多个精确值

  • cURL
  GET localhost:9200/megacorp/employee/_search
  Content-Type: application/json

  {
      "query":{
          "terms":{
              "age":[25,32]
          }
      }
  }
  • Response
  {"took":6,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":1.0,"_source":{"first_name":"Jane","last_name":"Smith","age":32,"about":"I like to collect rock albums","interests":["music"]}},{"_index":"megacorp","_type":"employee","_id":"1","_score":1.0,"_source":{"first_name":"John","last_name":"Smith","age":25,"about":"I love to go rock climbing","interests":["sports","music"],"views":1,"tags":["testing","search"]}}]}}

https://www.elastic.co/guide/cn/elasticsearch/guide/current/_aggregation_test_drive.html

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注