ElasticSearch文档
Elasticsearch是一个分布式的文档(document)存储引擎,可用于全文搜索。它可以实时存储并检索复杂数据结
构——序列化的JSON文档,当使用集群部署时,在任何节点都可以检索到存储的文档。
JSON文档
ElasticSearch的数据json格式进行存储,其中的每一个字段都可以被索引。ElasticSearch为每个字段都有一个反向索引用于快速检索,并且在同一个查询中可以使用多个字段的反向索引。
文档
文档是ElasticSearch中的最顶层结构被序列化程JSON数据,并做唯一表示存储。
文档的属性
文档包含了如下三个属性:
节点 | 说明 |
---|---|
_index | 文档存储的地方 |
_type | 文档代表的对象的类 |
_id | 文档唯一标识 |
_index
索引类似关系型数据口中的数据库,存储和索引数据的地方。实际上数据和索引时被存储在分片中,可以理解为分片是库的一部分。
_type
type可以理解成关系型数据库中的表,表内存储的对象有着相同的结构,即存储在通过type中的数据对象结构相同。type会有自己的映射,类似表的字段。
_type的命名规则可以大写,小写不能包含下划线或逗号。
_id
id时文档的唯一表示,由ElasticSearch自动生成
添加文档到索引
如果文档有自然的ID,假设索引名为info,type为student,id为1。
则索引操作为:
PUT /info/student/1 {
"name":"lcc",
"sex":"boy",
"birth":"20191001"
}
响应格式为:
{
"_index": "info",
"_type": "student",
"_id": "1",
"_version": 1,
"created": true
}
若数据没有自然ID,则可使用POST请求方法。
PUT请求时把文档存储到ID对应的空间,即id为1的存储空间。
POST请求则在文档下存储文档,即在type student中存储该文档,并返回生成标识ID(UUID)
POST请求格式如下:
POST /info/student/ {
"name":"lcc",
"sex":"boy",
"birth":"20191001"
}
响应内容:
{
"_index": "info",
"_type": "student",
"_id": "1",
"_id": "wM0OSFhDQXGZAWDf0-drSA",
"_version": 1,
"created": true
}
获取文档
添加pretty会让返回值更容易阅读
GET /info/student/1?pretty
返回:
{
"_index" : "info",
"_type" : "student",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"name":"lcc",
"sex":"boy",
"birth":"20191001"
}
}
获取文档中的部分内容
GET /info/student/1?_source=name,sex
响应:
{
"_index" : "info",
"_type" : "student",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"name":"lcc",
"sex":"boy"
}
}
更新文档
直接重新PUT,即可更新
POST /info/student/ {
"name":"lcc",
"sex":"girl",
"birth":"20191001"
}
响应内容:
{
"_index": "info",
"_type": "student",
"_id": "1",
"_id": "wM0OSFhDQXGZAWDf0-drSA",
"_version": 2,
"created": true
}
更新文档,ES内部操作顺序如下:
- 从旧文档中检索JSON
- 修改它
- 删除旧文档
- 索引新文档
局部更新文档
局部更新会覆盖修改的字段生成新的文档,直接重新PUT,即可更新
POST /info/student/_update {
"name":"LCC",
"birth":"20191101"
}
响应内容:
{
"_index": "info",
"_type": "student",
"_id": "1",
"_id": "wM0OSFhDQXGZAWDf0-drSA",
"_version": 4,
"created": true
}
更新可能不存在的文档
如果更新的文档可能不存在可以使用upsert,使得当记录不存在时插入一条数据,类型sql中的replace into
POST /info/student/_update {
"name":"LCC",
"upsert":{
"views":1
}
}
创建新文档
为保证插入时能插入,而不是更新。
PUT /info/student/1?op_type=create
或者:
PUT /info/student/_create
如果更新成功则返回201,失败返回409 :
{
"error" : "DocumentAlreadyExistsException[[website][4] [blog][123]:
document already exists]",
"status" : 409
}
删除文档
DELETE /info/student/1
如果成功则放回200,响应如下:
{
"found" : true,
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 3
}
如果文档不存在,则返回404,响应如下:
{
"found" : false,
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 4
}
注意不管成功或失败,都会记录该请求文档,并将_version加1。这是为了保证不同的操作顺序争取。
更新冲突
如果更新的文档的时候另一用户也在更新当前文档,则有可能造成数据丢失。
如果数据不在意时序性,即不关心数据更新的时间只关心要修改的列数据改变没有,如浏览人数。
那么在更新时,慢更新的会失败,然后重试。可以添加retry_on_conflict参数,设定更新重试次数
如:
POST /info/student/_update?retry_on_conflict=5<1> {
"name":"LCC_update",
"upsert":{
"views":1
}
}