Elasticsearch 相关
Created at 2019-08-21 Updated at 2020-07-29 Category 中间件 views
Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,建立在 Apache Lucene。
基础概念
Elasticsearch 是面向文档型数据库,一条数据就是一个文档。用 JSON 作为文档序列化的格式。
| Mysql | Elasticsearch |
|---|---|
| 数据库(Database) | 索引(Index) |
| 表(table) | 类型(Type) |
| 记录(low) | 文档(Document) |
| 字段(Columns) | 字段(Fields) |
一个索引只放一个类型
倒排索引
传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置。而倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典 + 映射表即为倒排索引。
倒排索引底层实现是基于 FST。
使用
创建索引
curl -XPUT http://localhost:9200/products?pretty pretty 代表格式化
删除索引
curl -X DELTE 'localhost:9200/weather'
创建类型
$ curl -H'Content-Type: application/json' -XPUT http://localhost:9200/test_index/_mapping/_doc?pretty -d'{
"properties": {
"title": { "type": "text", "analyzer": "ik_smart" },
"description": { "type": "text", "analyzer": "ik_smart" },
"price": { "type": "scaled_float", "scaling_factor": 100 }
}
}'
- “_doc” 是索引名称
- 提交数据中的
properties代表这个类型中各个字段的定义,其中 key 为字段名称,value 是字段的类型定义; - “analyzer”:
ik_smart代表这个字段需要使用 IK 中文分词器分词
创建文档
$ curl -X POST 'localhost:9200/accounts/person/1' -d '
{
"user": "李四",
"title": "工程师",
"desc": "系统管理"
}'
/accounts/person/1,最后的1是该条记录的 Id。它不一定是数字,任意字符串(比如abc)都可以。新增记录的时候,也可以不指定 Id,这时要改成 POST 请求。服务器返回的 json 对象里,_id 就是一个随机字符串
查看记录
$ curl 'localhost:9200/accounts/person/1?pretty=true'
返回的数据中,found字段表示查询成功,_source字段返回原始记录。果 Id 不正确,就查不到数据,found字段就是false。
删除记录
$ curl -X DELETE 'localhost:9200/accounts/person/1'
更新记录
更新记录就是使用 PUT 请求,重新发送一次数据。
记录的 Id 没变,但是版本(version)从1变成2,操作类型(result)从created变成updated,created字段变成false,因为这次不是新建记录。
返回所有记录
使用 GET 方法,直接请求/Index/Type/_search,就会返回所有记录。$ curl 'localhost:9200/accounts/person/_search'
返回结果的 took字段表示该操作的耗时(单位为毫秒),timed_out字段表示是否超时,hits字段表示命中的记录,里面子字段的含义如下。
- total:返回记录数
- max_score:最高的匹配程度
- hits:返回的记录组成的数组
数据查询
全文搜索
$ curl 'localhost:9200/accounts/person/_search' -d '
{
"query" : { "match" : { "desc" : "软件" }}
"from": 1,
"size": 1
}'
上面代码使用 match 查询,指定的匹配条件是desc字段里面包含”软件”这个词。
Elastic 默认一次返回10条结果,可以通过size字段改变这个设置。
还可以通过from字段,指定位移。
逻辑运算
如果有多个搜索关键词, Elastic 认为它们是 or 关系。
$ curl 'localhost:9200/accounts/person/_search' -d '
{
"query" : { "match" : { "desc" : "软件 系统" }}
}'
上面代码搜索的是软件 or 系统。
如果要执行多个关键词的 and 搜索,必须使用布尔查询。
$ curl 'localhost:9200/accounts/person/_search' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "desc": "软件" } },
{ "match": { "desc": "系统" } }
]
}
}
}'
短语搜索
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
match_prase 直接搜索 rock climing 不分词
布尔查询
filter/must/should/must_not
- filter 和 must 与 SQL 中的 and 类似,must 下的条件会参与 打分,而 filter 不会。
- must_not 和 must 相反,查询的文档必需不符合此类下的条件
- should 下的条件不需要全部满足,默认情况下只需要满足 should 下的一个条件即可,也可以通过 minimum_should_match 参数来改变需要满足的个数,满足的 should 条件越多,对应的文档的打分就越高,打分高的文档排序会靠前。
排序
'sort'=>['price'=>'desc']
多字段匹配查询
'must' => [
[
'multi_match' => [
'query' => 'iPhone',
'fields' => [
'title^3',
'long_title^2',
'description',
],
],
],
],
- query 代表要查询的关键字,fields代表要查询的字段,^代表字段的权重
多字段匹配查询支持 Nested 对象
定义索引时使用 copy_to 参数
“keyword” 是字符串类型的一种,告诉 Elasticsearch 不需要对这个字段做分词,通常用于邮箱、标签、属性等字段。
scaled_float 代表一个小数位固定的浮点型字段,与 Mysql 的 decimal 类型类似,后面的 scaling_factor 用来指定小数位精度,100 就代表精确到小数点后两位。
“nested” 代表这个字段是一个复杂对象,由下一级的 properties 字段定义这个对象的字段。