Elasticsearch RESTFul API Basic

2020-12-10

Elasticsearch 的 RESTFul API 虽然提供了方便的查询接口, 但是多变的组合方式很让人头疼.

ES 使用了 RESTFul 风格的 HTTP Method, 但跟经典设计有些区别:

  • 没有 MATCH, 用 POST 加 _update 代替
  • PUT 新建索引, 新建或覆盖文档 (必须指明ID)
  • POST 新建或修改文档, 其他设置

查看索引是否存在

HEAD /marks

创建索引

PUT /marks

{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "id": {
        "type": "long"
      },
      "created_at": {
        "type": "date"
      },
      "updated_at": {
        "type": "date"
      },
      "user_id": {
        "type": "long"
      },
      "url": {
        "type": "keyword"
      },
      "tag": {
        "type": "keyword"
      },
      "hash_key": {
        "type": "keyword"
      },
      "selection": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "comment": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart",
        "fields": {
          "keyword": {
            "ignore_above": 256,
            "type": "keyword"
          }
        }
      }
    }
  }
}

查看索引列表

GET /_cat/indices

response 为按行分隔的文本, 非 JSON

查看索引详情

GET /marks

  • 只查看索引映射: GET /marks/_mappings
  • 只查看索引设置: GET /marks/_settings

删除索引

DELETE /marks

新建文档

PUT 必须制定文档 _id, POST 可选自动生成 _id(推荐指定).

7.x 以后的版本限制每个索引必须使用相同的类型, 即用 _doc 占位.

PUT /marks/_doc/1

{
  "id": 1,
  "created_at": "2020-12-08T15:57:09.706469055+08:00",
  "updated_at": "2020-12-08T15:57:09.706469055+08:00",
  "user_id": 123,
  "url": "http://localhost",
  "tag": "red",
  "selection": "My rabbit jumps",
  "comment": "静安嘉里中心"
}

POST /marks/_doc/2

{
  "id": 2,
  "created_at": "2020-12-08T15:57:09.706469055+08:00",
  "updated_at": "2020-12-08T15:57:09.706469055+08:00",
  "user_id": 123,
  "url": "http://localhost",
  "tag": "green",
  "selection": "Jumping jack rabbits",
  "comment": "国金中心"
}

删除文档 By _id

DELETE /marks/_doc/1

修改文档部分字段

POST /marks/_update/1

{
  "doc": {
    "new_filed": "simple str"
  }
}

根据具体值查找

根据 id 的精确值查找:

SQL: select * from marks where id = 1

ES :

GET /marks/_search

{
  "query": {
    "term": {
      "id": {
        "value": 1
      }
    }
  }
}

根据 id 数组的精确值查找:

SQL: select * from marks where id in (1, 2)

ES:

GET /marks/_search

{
  "query": {
    "terms": {
      "id": [
        1,
        2
      ]
    }
  }
}

查询模板

常用的查询都可以用 bool 查询包装, 很多工具也是这样做的.

  • must_not 一定不命中, 如果命中即排除;
  • must 要求其中每个查询都命中, 即 AND 的关系; 会计算分数;
  • should 如果命中则有加分, 即 OR 的关系;
  • filter 同 must 但不计算分数;

sql: SELECT*FROM marks LIMIT 20 OFFSET 0

GET /marks/_search

{
  "query": {
    "bool": {
      "must_not": [],
      "must": [],
      "should": [],
      "filter": []
    }
  },
  "from": 0,
  "size": 20,
  "sort": [],
  "aggs": {}
}

term

marks 中 comment, 一份数据有两种索引方式:

  • text: 根据分析器先拆分 token 再录入倒排索引;
  • keyword: 原样存储.

term 是 精确值匹配, 在 comment.keyword 中搜索:

sql:

select * from marks where `comment.keyword` = '国金中心'

ES:

GET /marks/_search

{
  "query": {
    "term": {
      "comment.keyword": {
        "value": "国金中心"
      }
    }
  }
}

分析器

GET /marks/_analyze

{
  "analyzer": "ik_smart",
  "text": [
    "静安中心"
  ]
}

match

match 是构建在 term 的基础上的. 录入文档时, 文档经过 analyzer 分词, 搜索文本时, 文本经过 search_analyzer 分词, 然后分词和分词 term 精确匹配.

比如在 comment 上搜索: 静安中心.

先经过 search_analyzer 得到 token 静安中心, 然后把他们带入倒排索引分别匹配:

sql: select * from marks where comment = '静安' or comment = '中心'

(这里的 sql 已经不能准确表达了, 因为 comment 是一组值.)

ES:

GET /marks/_search

{
  "query": {
    "match": {
      "comment": "静安中心"
    }
  }
}

如果没有专门指定 search_analyzer, 那么他就跟随字段的 analyzer.

multi_match

GET /marks/_search

{
  "query": {
    "multi_match": {
      "query": "静安中心",
      "type": "best_fields", 
      "fields": [
        "comment",
        "selection"
      ]
    }
  }
}

muti_match 是对 match 的包装, 他在多个字段上执行 match, 根据 type 进行多种策略的算分和返回.

  • best_fields, 默认的type, 只看得分最高的字段;
  • most_fields, 得分最高的字段占大头, 其他字段有相应的加分, 忽略不相关的长尾;
  • cross_fields, 多字段融合, 综合计算词频.

查询分析

POST /marks/_validate/query?explain

{
  "query": {
    "multi_match": {
      "query": "静安中心",
      "type": "most_fields",
      "fields": [
        "comment",
        "selection"
      ]
    }
  }
}

开发阶段可以利用 _validate 查看 query 是否合法, 查看解析后的搜索逻辑.