diff --git a/elastic search/elastic search.md b/elastic search/elastic search.md index 261dba2..597aa6d 100644 --- a/elastic search/elastic search.md +++ b/elastic search/elastic search.md @@ -170,6 +170,322 @@ POST books/_doc "_primary_term": 1 } ``` +#### 向索引中添加多个document +可以使用`/_bulk`接口来在单个请求中添加多个document。`_bulk`请求的请求体由多个json串组成,json串之间通过换行符分隔。 + +bulk请求示例如下所示: +``` +POST /_bulk +{ "index" : { "_index" : "books" } } +{"name": "Revelation Space", "author": "Alastair Reynolds", "release_date": "2000-03-15", "page_count": 585} +{ "index" : { "_index" : "books" } } +{"name": "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328} +{ "index" : { "_index" : "books" } } +{"name": "Fahrenheit 451", "author": "Ray Bradbury", "release_date": "1953-10-15", "page_count": 227} +{ "index" : { "_index" : "books" } } +{"name": "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268} +{ "index" : { "_index" : "books" } } +{"name": "The Handmaids Tale", "author": "Margaret Atwood", "release_date": "1985-06-01", "page_count": 311} +``` + +如果上述请求被正确处理,将会得到如下返回体: +```json +{ + "errors": false, + "took": 29, + "items": [ + { + "index": { + "_index": "books", + "_id": "QklI2IsBaSa7VYx_Qkh-", + "_version": 1, + "result": "created", + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 1, + "_primary_term": 1, + "status": 201 + } + }, + { + "index": { + "_index": "books", + "_id": "Q0lI2IsBaSa7VYx_Qkh-", + "_version": 1, + "result": "created", + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 2, + "_primary_term": 1, + "status": 201 + } + }, + { + "index": { + "_index": "books", + "_id": "RElI2IsBaSa7VYx_Qkh-", + "_version": 1, + "result": "created", + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 3, + "_primary_term": 1, + "status": 201 + } + }, + { + "index": { + "_index": "books", + "_id": "RUlI2IsBaSa7VYx_Qkh-", + "_version": 1, + "result": "created", + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 4, + "_primary_term": 1, + "status": 201 + } + }, + { + "index": { + "_index": "books", + "_id": "RklI2IsBaSa7VYx_Qkh-", + "_version": 1, + "result": "created", + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 5, + "_primary_term": 1, + "status": 201 + } + } + ] +} +``` + +### 定义mapping和data type +#### 使用dynamic mapping +当使用dynamic mapping时,elastic search默认情况下将会自动为新field创建mapping。上述示例中向索引中添加的document都使用了dynamic mapping,因为在创建索引时,并没有手动指定mapping。 + +可以向`books`索引中新增一个document,新增document中包含当前索引documents中不存在的字段: +``` +POST /books/_doc +{ + "name": "The Great Gatsby", + "author": "F. Scott Fitzgerald", + "release_date": "1925-04-10", + "page_count": 180, + "language": "EN" +} +``` +此时,针对`books`索引,新字段`language`之前并不存在,会以`text`的data type被新增到mapping中。 + +可以通过`/{index_uid}/_mapping`请求来查看索引的mapping信息: +``` +GET /books/_mapping +``` +其返回的响应为: +```json +{ + "books": { + "mappings": { + "properties": { + "author": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "new_field": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "page_count": { + "type": "long" + }, + "release_date": { + "type": "date" + } + } + } + } +} +``` + +#### 手动指定索引的mapping +如下示例会展示如何在创建索引时手动指定索引的mapping: +``` +PUT /my-explicit-mappings-books +{ + "mappings": { + "dynamic": false, + "properties": { + "name": { "type": "text" }, + "author": { "type": "text" }, + "release_date": { "type": "date", "format": "yyyy-MM-dd" }, + "page_count": { "type": "integer" } + } + } +} +``` + +上述示例中请求体含义如下: +- `"dynamic": false`: 在索引中禁用dynamic mapping,如果提交的document中包含了mapping中不存在的field,那么该提交的document将会被拒绝 +- `"properties"`:properties属性定义了document中的fields及其数据类型 + +#### 将dynamic mapping和手动指定mapping相结合 +如果在创建索引时手动指定了索引的mapping,那么在向索引中添加document时,document必须符合索引的定义。 + +如果要结合dynamic mapping和手动指定mapping,有如下两种方式: +- 使用update mapping Api +- 手动指定mapping时,将dynamic设置为true,此时向document中添加new field时无需对mapping执行update + +### 搜索索引 +#### 搜索所有文档 +``` +GET books/_search +``` +上述请求将会搜索`books`索引中所有的文档 + +响应如下: +```json +{ + "took": 2, + "timed_out": false, + "_shards": { + "total": 5, + "successful": 5, + "skipped": 0, + "failed": 0 + }, + "hits": { + "total": { + "value": 7, + "relation": "eq" + }, + "max_score": 1, + "hits": [ + { + "_index": "books", + "_id": "CwICQpIBO6vvGGiC_3Ls", + "_score": 1, + "_source": { + "name": "Brave New World", + "author": "Aldous Huxley", + "release_date": "1932-06-01", + "page_count": 268 + } + }, + ... (truncated) + ] + } +} +``` + +其中,响应体的字段含义如下: +- `took`:es执行该搜索请求花费的时间,单位为ms +- `time_out`:代表该请求是否超时 +- `_shards`:代表该请求的分片数和成功数 +- `hits`:hits对象中包含了执行结果 +- `total`:total对象中包含了匹配结果的总数信息 +- `max_score`:max_score包含了在所有匹配documents中最高的relavance score +- `_index`:该字段代表了document所属的索引 +- `_id`:该字段代表document的唯一标识id +- `_score`:`_score`字段代表当前document的relavance score +- `_source`:该字段包含了indexing过程中提交的原始json对象 + +#### match请求 +可以通过match请求来查询特定field中包含指定值的documents。这是全文本查询的标准查询。 + +如下示例中会查询索引中`name` field中包含`brave`的文档: +``` +GET books/_search +{ + "query": { + "match": { + "name": "brave" + } + } +} +``` + +响应体结构如下: +```json +{ + "took": 9, + "timed_out": false, + "_shards": { + "total": 5, + "successful": 5, + "skipped": 0, + "failed": 0 + }, + "hits": { + "total": { + "value": 1, + "relation": "eq" + }, + "max_score": 0.6931471, + "hits": [ + { + "_index": "books", + "_id": "CwICQpIBO6vvGGiC_3Ls", + "_score": 0.6931471, + "_source": { + "name": "Brave New World", + "author": "Aldous Huxley", + "release_date": "1932-06-01", + "page_count": 268 + } + } + ] + } +} +``` + +#### 删除索引 +如果要删除创建的索引从头开始,可以使用如下方式: +``` +DELETE /books +DELETE /my-explicit-mappings-books +``` +删除索引将会永久删除其document、shards、元数据。 + + + +