我们知道Lucene检索的原理是创建倒排索引,ES的使用步骤也是类似的,我们需要先导入数据创建索引,如果数据发生变化也需要进行对应索引的增删改查操作,具体检索时则需要调用相应接口从索引中进行搜索。这些操作ES提供了RestfulAPI,我们可以使用Postman工具或Kibana进行测试,这篇笔记我们简单了解学习。
index:ES中的index(索引)定义包含若干数据的字段,以及相关设置,具体数据会关联索引来创建,ES会自动创建倒排索引,检索时可以在指定索引字段中实现。
document:document(文档)可以理解为具体的数据,我们以包含若干字段的JSON格式上传给ES。
shard:ES是分布式的检索系统,一个分布式节点的存储空间是有限的,但ES支持shard(数据分片),可以将一组巨大的数据分割存储到多个分布式节点上。
replica:replica(副本集)指数据的副本,数据副本必须分布在不同节点上以保证可用性,如果创建索引时指定了超出可用节点数的副本集,索引是无法创建成功的。
ES的API设计遵循了统一的格式,这里以curl
命令为例:
curl ‐X <VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' ‐d '<BODY>'
参数 | 说明 |
---|---|
HTTP请求方法,包括GET、POST、PUT、DELETE | |
协议,http或https | |
请求主机 | |
请求端口,默认为9200 | |
API端点 | |
查询参数 | |
JSON请求体 |
下面例子中,我们创建了一个名为idx_article
的索引。
PUT http://localhost:9200/idx_article
请求体:
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
settings
字段设置了索引的分片和副本数,mappings
字段设置了具体的索引字段等信息。
DELETE http://localhost:9200/idx_article
查询所有索引:
GET http://localhost:9200/_all
查询索引详情:
http://localhost:9200/idx_article
这里我们创建了一条主键为1
的数据:
POST http://localhost:9200/idx_article/_doc/1
{
"title": "测试标题1",
"content": "这是一段字符串测试内容。"
}
如果对应主键文档已经存在,会自动执行更新。
POST http://localhost:9200/idx_article/_bulk
API中使用bulk
命令进行批量更新,但这里注意该命令的格式定义比较奇葩,它并非标准JSON格式,为如下形式:
{"index":{"_id":"1"}}
{"title": "测试标题1","content": "这是一段字符串测试内容。"}
{"index":{"_id":"2"}}
{"title": "测试标题2","content": "这也是一段字符串测试内容。"}
每条批量操作为两行,第一行包括操作类型、主键等信息,第二行是具体的数据字段,操作之间必须插入空行作为分隔。
DELETE http://localhost:9200/idx_article/_doc/1
POST http://localhost:9200/idx_article/_bulk
{"delete":{"_id":"1"}}
{"delete":{"_id":"2"}}
GET http://localhost:9200/idx_article/_search
ES的检索RestfulAPI设计的极为怪异,它是带有请求体的GET
请求,这可能造成有些语言HTTP客户端库的不兼容。请求路径如下:
GET http://localhost:9200/idx_article/_search
match:对查询关键字分词,再按分词搜索。
{
"query": {
"match": {
"content": "内容"
}
}
}
multi_match:同match,但在多个字段中搜索。
{
"query": {
"multi_match": {
"query": "一段",
"fields": [
"title",
"content"
]
}
}
}
match_phrase:对关键字整体(不分词)进行搜索。
{
"query": {
"match_phrase": {
"content": "一段内容"
}
}
}
ES支持为搜索结果中的关键词分词加上HTML标签,这样便于我们实现搜索关键字高亮。
{
"query": {
"match": {
"content": "一段内容"
}
},
"highlight": {
"pre_tags": "<span color='red'>",
"post_tags": "</span>",
"fields": {
"content": {}
}
}
}