转载自:https://blog.youkuaiyun.com/chengyuqiang/column/info/18392,ES版本号6.3.0
文档路由:
(1)指定路由
PUT blog/csdn/3?routing=chengyuqiang
{
"id":3,
"title":"Java简介",
"author":"chengyuqiang",
"content":"Oracle Java"
}
返回
{
"_index": "blog",
"_type": "csdn",
"_id": "3",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 4
}
(2)根据路由查询
GET blog/_search?routing=chengyuqiang
返回
{
"took": 36,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "blog",
"_type": "csdn",
"_id": "3",
"_score": 1,
"_routing": "chengyuqiang",
"_source": {
"id": 3,
"title": "Java简介",
"author": "chengyuqiang",
"content": "Oracle Java"
}
}
]
}
}
(3)删除
DELETE blog/csdn/3
返回
{
"_index": "blog",
"_type": "csdn",
"_id": "3",
"_version": 1,
"result": "not_found",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 4,
"_primary_term": 4
}
再次删除,带上错误路由
DELETE blog/csdn/3?routing=hadron
返回
{
"_index": "blog",
"_type": "csdn",
"_id": "3",
"_version": 2,
"result": "not_found",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 5,
"_primary_term": 4
}
正确的删除
DELETE blog/csdn/3?routing=chengyuqiang
返回
{
"_index": "blog",
"_type": "csdn",
"_id": "3",
"_version": 2,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 4
}
Mapping概述
前文已经把ElasticSearch的核心概念和关系数据库做了一个对比,索引(index)相当于数据库,类型(type)相当于数据表,映射Mapping相当于数据库表的表结构。ElasticSearch中的映射(Mapping)用来定义一个文档,可以定义所包含的字段以及字段类型、分词器及属性等。
映射可以分为动态映射和静态映射
(1)动态映射
我们知道,在关系数据库中,需要事先创建数据库,然后在该数据库实例下创建数据表,然后才能在该数据表中插入数据。而ElasticSearch中不需要实现定义映射(Mapping),文档写入ElasticSearch时,会根据字段自动识别类型,这种机制称为动态映射。
(2)静态映射
当然,在ElastIcSearch中也可以事先定义好映射,包含文档的各个字段及其类型等,这种方式称之为静态映射。
动态映射实例
(1)新建索引
PUT book
返回
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "book"
}
(2)查看空mapping
GET book/_mapping
返回
{
"book": {
"mappings": {}
}
}
(3)插入文档
it类型标识IT类书籍
PUT book/it/1
{
"bookId":1,
"bookName":"Java程序设计",
"publishDate":"2018-01-12"
}
返回
{
"_index": "book",
"_type": "it",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
(4)再次查看映射
GET book/_mapping
返回
{
"book": {
"mappings": {
"it": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"publishDate": {
"type": "date"
}
}
}
}
}
}
(5)解读
bookId字段推测为long型,bookName字段推测为text类型,publishDate字段推测为date类型,这些推测都是我们可以接受的。可见ElasticSearch的动态映射十分强大。
动态映射规则
动态映射可以帮助我们在创建索引后直接将文档数据写入ElasticSearch,让我们尽快享受到ElasticSearch检索功能。在实际项目中,如果在导入数据前不能确定包含哪些字段或者不方便确定字段类型,可以使用动态映射。当向ElasticSearch写入一个新文档时,需要一个之前没有的字段,会通过动态映射来推断该字段类型。
静态映射
动态映射的自动类型推测功能并不是100%正确的,这就需要静态映射机制。静态映射与关系数据库中创建表语句类似,需要事先指定字段类型。相对于动态映射,静态映射可以添加更加详细字段类型、更精准的配置信息等。
(1)新建映射
在es6.x中创建的索引只允许每个索引有单一类型。任何名字都可以用于这个类型,但是只能有一个。
PUT books
{
"mappings":{
"it": {
"properties": {
"bookId": {"type": "long"},
"bookName": {"type": "text"},
"publishDate": {"type": "date"}
}
}
}
}
返回
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "books"
}
(2)查看映射
GET books/_mapping
返回
{
"books": {
"mappings": {
"it": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text"
},
"publishDate": {
"type": "date"
}
}
}
}
}
}
(3)插入文件数据
PUT books/it/1
{
"bookId":"1",
"bookName":"Java",
"publishDate":"2018-01-12"
}
返回
{
"_index": "books",
"_type": "it",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
(4)检索
GET books/it/1
返回
{
"_index": "books",
"_type": "it",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"bookId": "1",
"bookName": "Java",
"publishDate": "2018-01-12"
}
}
静态+动态
PUT books/it/2
{
"bookId":"2",
"bookName":"Hadoop",
"author":"chengyuqiang",
"publishDate":"2018-01-13"
}
返回
{
"_index": "books",
"_type": "it",
"_id": "2",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
查看Mapping
GET books/_mapping
返回
{
"books": {
"mappings": {
"it": {
"properties": {
"author": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"bookId": {
"type": "long"
},
"bookName": {
"type": "text"
},
"publishDate": {
"type": "date"
}
}
}
}
}
}
Type设计失误
类型是Elasticsearch的一个设计失误,6.0开始后面的版本将不再支持,官方说明请参见
(1)为什么映射类型被删除?
一开始,我们我们谈到 一个 ES的索引类似于关系型数据库中的数据库,一个映射类型则相当于关系型数据库中的一张表。
这是一个错误的类比,导致了错误的假设。在一个关系型数据库中,表之间是相互独立的。一个表中的列与另一个表中同名的列没有关系。然而在映射类型中却不是这样的。
在一个Elasticsearch的索引中,有相同名称字段的不同映射类型在Lucene内部是由同一个字段支持的。换言之,看下面的这个例子,user 类型中的 user_name字段和tweet类型中的user_name字段实际上是被存储在同一个字段中,而且两个user_name字段在这两种映射类型中都有相同的定义(如类型都是 text或者都是date)。
这会导致一些问题,比如,当你希望在一个索引中的两个映射类型,一个映射类型中的 deleted 字段映射为一个日期数据类型的字段,而在另一个映射类型中的deleted字段映射为一个布尔数据类型的字段,这就会失败。
最重要的是,在一个索引中存储那些有很少或没有相同字段的实体会导致稀疏数据,并且干扰Lucene有效压缩文档的能力。
基于这些原因,我们决定从Elasticsearch中删除映射类型的概念。