一,ES概述

_index:索引库,类似于关系型数据库中的“数据库”

_type:类型,类似于关系型数据库中表(注意只能小写),不能包含下划线。

_id:文档的唯一标识,类似于关系型数据库主键,当你创建一个文档不指定_id 的话,Elasticsearch会给你自动创建。

二,文档的简单crud操作

1,ADD

POST /es/user/
{
  "name": "沙滩上遇见代码4",
  "age": 30,
  "sex": 1,
  "desc": "浪啊"
}

响应:
{
  "_index" : "es",
  "_type" : "user",
  "_id" : "9obkwnMBRF-jnVEuACKM",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 12,
  "_primary_term" : 10
}

注:/es/user/后面可以自定义Id,不指定的情况下es会自动创建

2,DELETE

DELETE /es/user/9obkwnMBRF-jnVEuACKM

响应:
{
  "_index" : "es",
  "_type" : "user",
  "_id" : "9obkwnMBRF-jnVEuACKM",
  "_version" : 2,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 14,
  "_primary_term" : 10
}

3,UPDATE(局部&全局更新),更新过程:1. 从旧文档中检索JSON,2. 修改它,3. 删除旧文档,4. 索引新文档

原数据:

{
    "_index" : "es",
    "_type" : "user",
    "_id" : "3",
    "_score" : 0.28529924,
    "_source" : {
        "name" : "沙滩上遇见代码",
        "age" : 30,
        "sex" : 1,
        "desc" : "浪啊"
    }
}
POST /es/user/3/_update
{
  "doc": {
    "name": "沙滩上遇见代码+美女"
  }
}

更新后:
{
    "_index" : "es",
    "_type" : "user",
    "_id" : "3",
    "_score" : 0.28529924,
    "_source" : {
        "name" : "沙滩上遇见代码+美女",
        "age" : 30,
        "sex" : 1,
        "desc" : "浪啊"
    }
}

注:局部更新 /es/user/3/后加_update
PUT /es/user/3
{
  "doc": {
    "name": "沙滩上遇见代码+美女娜美"
  }
}

更新后:
{
    "_index" : "es",
    "_type" : "user",
    "_id" : "3",
    "_score" : 0.28529924,
    "_source" : {
        "name" : "沙滩上遇见代码+美女娜美"
    }
}

注:全局更新 没有更新的字段将去除

4,QUERY

4.1,通过文档ID获取

GET /es/user/3

注:通过单个Id查询

GET /es/user/_mget
{
  "ids": ["1","2"]
}

注:通过多个Id查询

4.2,空搜索=查询所有

GET /es/user/_search

4.3,根据条件搜索

GET /es/user/_search?q=name:代码

## 查询的参数使用json结构,并通过_source只查询哪些字段
GET /es/user/_search
{
  "query": {
    "match": {
      "name": "代码"
    }
  },
  "_source": ["name","desc"]
}

注:
MUST:+表示并且,相当于AND
SHOULD:空格表示或,相当于OR 
MUST_NOT:-表示非

4.4,排序

GET /es/user/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "代码"
          }
        }
      ], 
      "filter": {
        "range": {
          "age": {
            "gte": 1,
            "lte": 30
          }
        }
      }
    }
  }
}

注:过滤器filter (gt 大于 gte 大于等于 lt 小于 lte 小于等于!)

4.5,分页查询

GET /es/user/_search
{
  "sort": [
    {
      "age": {
        "order": "asc"
      }
    }
  ],
  "from": 0,
  "size": 10
}

注:分页查询 (from=开始位置,size=limit)

4.6,高亮查询并自定义高亮条件

GET /es/user/_search
{
  "query": {
    "match": {
      "name": "搬运工"
    }
  },
  "highlight": {
    "pre_tags": "<span style='color: red'>", 
    "post_tags": "</span>", 
    "fields": {
      "name": {}
    }
  }
}

4.7,高级搜索-提高精度(Improving Precision)

GET /es/user/_search
{
  "query": {
    "match": {
      "name": {
        "query": "代码 搬运工"
      }
    }
  }
}

上面的多词查询(Multi-word Queries),任意一个词条匹配成功就算作匹配的话,会导致最终结果中有很多看似无关的匹配。它是一个霰弹枪式的策略(Shotgun Approach)。如果我们只想要查询包含了所有查询词条的文档。换言之,相比"代码 OR 搬运工",我们更想要的结果是"代码 AND 搬运工"

解决策:match查询接受一个operator参数,该参数的默认值是"or"。你可以将它改变为"and"来要求所有的词条都需要被匹配:

GET /es/user/_search
{
  "query": {
    "match": {
      "name": {
        "query": "代码 搬运工",
        "operator": "and"
      }
    }
  }
}

4.8,高级搜索-控制精度(Controlling Precision)

通过上面的多词查询提高精度查询中我们发现了一个问题,即在all和any中选择有种非黑即白的感觉。比如这样一个情况:用户写了3个查询词条,而一份文档只包含了其中的2个呢?将"operator"设置成"and"会将它排除在外。显然此时查询结果为空。

有时候这正是你想要的,但是对于大多数全文搜索的使用场景,你会希望将相关度高的文档包含在结果中,将相关度低的排除在外。换言之,我们需要一种介于两者中间的方案。

match查询支持minimum_should_match参数,它能够让你指定有多少词条必须被匹配才会让该文档被当做一个相关的文档。尽管你能够指定一个词条的绝对数量,但是通常指定一个百分比会更有意义,因为你无法控制用户会输入多少个词条。

GET /es/user/_search
{
  "query": {
    "match": {
      "name": {
        "query": "代码 搬运工",
        "minimum_should_match": "50%"
      }
    }
  }
}