elasticsearch增删改查【基础概念】RESTful API
发布时间: 2024-03-19 21:14:04 阅读量: 42 订阅数: 36
# 1. 引言
- 1.1 什么是elasticsearch
- 1.2 elasticsearch的优势和应用场景
- 1.3 RESTful API简介
# 2. elasticsearch基础概念
### 2.1 索引(Index)
Elasticsearch中的索引类似于传统数据库中的数据库,它用于存储一系列相关数据。一个索引可以包含多种不同类型的文档,每个文档都有一个唯一的ID来标识。
```python
# Python示例代码
from elasticsearch import Elasticsearch
# 创建索引
es.indices.create(index='my_index')
```
**总结:** 索引是elasticsearch中用于存储数据的结构,类似于数据库。
### 2.2 类型(Type)
在较新的elasticsearch版本中,类型被逐渐废弃,将来可能会被完全移除。在旧版中,一个索引可以包含多个类型,每个类型有自己的映射,但现在建议一个索引只有一个类型,多种数据结构可以通过字段来区分。
```java
// Java示例代码
CreateIndexResponse createIndexResponse = client.admin().indices().prepareCreate("my_index").get();
```
**总结:** 类型用于定义文档的映射结构,但在最新版本中已逐渐被废弃。
### 2.3 文档(Document)
文档是elasticsearch中最小的数据单元,它以JSON格式存储在索引中。每个文档都有一个唯一的ID用于标识,可以是自动生成的也可以是用户自定义的。
```javascript
// JavaScript示例代码
// 添加文档
client.index({
index: 'my_index',
id: '1',
body: {
title: 'Sample Document',
content: 'This is a sample document for demonstration.'
}
})
```
**总结:** 文档是elasticsearch中最基本的数据单元,以JSON形式存储在索引中。
### 2.4 映射(Mapping)
映射定义了文档中每个字段的数据类型和属性。通过映射,可以确定字段是文本类型、日期类型、数值类型等。良好的映射可以提高搜索性能和精确度。
```go
// Go示例代码
mapping := `
{
"properties": {
"title": {
"type": "text"
},
"content": {
"type": "text"
}
}
}
`
createIndexWithMapping("my_index", mapping)
```
**总结:** 映射指定了文档中字段的数据类型和属性,有助于提高搜索的准确性。
在elasticsearch中,理解这些基础概念对于进行数据操作是非常重要的。下一章我们将介绍如何使用RESTful API进行数据的增加操作。
# 3. 使用RESTful API进行数据增加
### 3.1 探索elasticsearch的基本API操作
在elasticsearch中,可以使用RESTful API来进行数据增加操作。首先,我们需要了解elasticsearch的基本API操作方法。
### 3.2 使用HTTP POST请求添加文档
下面是使用HTTP POST请求向elasticsearch添加单个文档的示例代码(使用Python语言):
```python
import requests
# 定义elasticsearch主机地址和索引名
url = 'http://localhost:9200/my_index/my_type'
headers = {'Content-Type': 'application/json'}
# 添加的文档数据
document = {
'title': 'Elasticsearch Data',
'content': 'Adding a document using RESTful API'
}
# 发起POST请求
response = requests.post(url, headers=headers, json=document)
# 检查请求是否成功
if response.status_code == 201:
print("Document added successfully!")
else:
print("Failed to add document.")
```
**代码总结:** 以上代码通过HTTP POST请求向elasticsearch中名为"my_index"的索引的类型"my_type"添加了一个文档。如果添加成功,将输出"Document added successfully!"。
### 3.3 利用Bulk API批量添加文档
除了单个文档的添加,elasticsearch还提供了Bulk API用于批量添加文档。下面是一个批量添加文档的示例代码(使用Java语言):
```java
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
// 创建RestHighLevelClient
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")
)
);
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.add(new IndexRequest("my_index", "my_type", "1")
.source(XContentType.JSON,"title","Document 1"));
bulkRequest.add(new IndexRequest("my_index", "my_type", "2")
.source(XContentType.JSON,"title","Document 2"));
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
// 处理响应结果
if (bulkResponse.hasFailures()) {
System.out.println("One or more documents failed to add.");
} else {
System.out.println("Bulk documents added successfully.");
}
// 关闭client
client.close();
```
**代码总结:** 以上代码使用Bulk API批量添加了两个文档到名为"my_index"的索引中。通过检查响应结果,可以确定是否添加成功。
通过以上代码示例,我们可以了解如何使用RESTful API进行elasticsearch数据的增加操作。
# 4. 使用RESTful API进行数据删除
### 4.1 利用HTTP DELETE请求删除文档
在elasticsearch中,我们可以使用HTTP DELETE请求来删除单个文档。下面是一个简单的Python示例代码,演示如何使用elasticsearch-py库发送DELETE请求删除一个文档:
```python
from elasticsearch import Elasticsearch
# 创建连接
es = Elasticsearch(['localhost:9200'])
# 删除文档
res = es.delete(index='my_index', doc_type='my_type', id=1)
print(res)
```
**代码说明:**
- 首先,我们建立与elasticsearch的连接。
- 然后,使用`delete()`方法指定要删除的文档的索引、类型和文档ID。
- 最后,打印删除操作的结果。
**结果说明:**
如果删除成功,将会返回一个类似`{'found': True, '_index': 'my_index', '_type': 'my_type', '_id': '1', '_version': 2, 'result': 'deleted', '_shards': {'total': 2, 'successful': 1, 'failed': 0}}`的JSON响应。
### 4.2 删除索引及其所有文档
除了删除单个文档外,我们还可以删除整个索引及其包含的所有文档。以下是一个简单的Java示例代码:
```java
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
// 删除索引
DeleteIndexRequest request = new DeleteIndexRequest("my_index");
AcknowledgedResponse deleteIndexResponse = client.indices().delete(request);
// 关闭连接
client.close();
```
**代码说明:**
- 首先,我们创建了一个RestHighLevelClient连接到elasticsearch。
- 然后,使用`DeleteIndexRequest`指定要删除的索引名称。
- 最后,通过调用`client.indices().delete(request)`方法删除索引。
**结果说明:**
如果删除索引成功,`deleteIndexResponse.isAcknowledged()`方法将返回`true`。
### 4.3 使用Bulk API批量删除文档
除了单个删除或删除索引外,我们还可以通过批量删除接口Bulk API来删除多个文档。以下是一个简单的Go示例代码:
```go
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/elastic/go-elasticsearch/v8"
)
func main() {
cfg := elasticsearch.Config{
Addresses: []string{
"http://localhost:9200",
},
}
es, _ := elasticsearch.NewClient(cfg)
var body = []map[string]interface{}{
{ "delete": { "_index": "my_index", "_id": "1"} },
{ "delete": { "_index": "my_index", "_id": "2"} },
}
res, _ := es.Bulk(
strings.NewReader(fmt.Sprintf("%v\n", body)),
es.Bulk.WithContext(context.Background()),
)
defer res.Body.Close()
var r map[string]interface{}
json.NewDecoder(res.Body).Decode(&r)
fmt.Printf("Response: %v", r)
}
```
**代码说明:**
- 首先,我们建立了与elasticsearch的连接。
- 接着,使用Bulk API批量删除文档,指定要删除的文档的索引和ID。
- 最后,解析响应并打印结果。
**结果说明:**
如果批量删除成功,将会返回相关的响应结果。
# 5. 使用RESTful API进行数据更新
在elasticsearch中,我们可以使用RESTful API来对数据进行更新操作。在这一章节中,将详细介绍如何使用不同语言(Python、Java、Go、JavaScript)的代码示例来更新elasticsearch中的文档。
### 5.1 使用HTTP POST请求更新文档
#### Python示例代码:
```python
import requests
url = 'http://localhost:9200/my_index/my_type/1/_update'
headers = {'Content-Type': 'application/json'}
data = {
"doc": {
"name": "Updated Name",
"age": 30
}
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
```
**代码解释:**
- 这段Python代码使用HTTP POST请求来更新id为1的文档,将name字段更新为"Updated Name",将age字段更新为30。
- 请求中的`doc`字段表示要更新的内容。
**结果说明:**
- 如果操作成功,会返回更新后的文档信息。
#### Java示例代码:
```java
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ElasticUpdateDoc {
public static void main(String[] args) {
HttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://localhost:9200/my_index/my_type/1/_update");
httpPost.addHeader("Content-Type", "application/json");
String json = "{\"doc\" : {\"name\": \"Updated Name\", \"age\": 30}}";
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
try {
HttpResponse response = httpClient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
BufferedReader rd = new BufferedReader(new InputStreamReader(responseEntity.getContent()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
**代码解释:**
- 这段Java代码使用Apache HttpClient发送HTTP POST请求更新id为1的文档。
- 请求中的JSON数据表示要更新的字段及其对应的值。
**结果说明:**
- 如果更新成功,将返回更新后的文档信息。
### 5.2 部分更新文档的处理方式
有时候我们可能只想更新文档的部分字段而不是整个文档,这时可以使用脚本来实现部分更新。接下来我们将介绍如何部分更新文档。
#### Go示例代码:
```go
package main
import (
"bytes"
"fmt"
"net/http"
)
func main() {
url := "http://localhost:9200/my_index/my_type/1/_update"
data := []byte(`{"script" : {"source": "ctx._source.name = 'Updated Name'","lang": "painless"}}`)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
}
```
**代码解释:**
- 这段Go代码使用HTTP POST请求更新id为1的文档,仅更新了name字段,将其值修改为"Updated Name"。
- 通过`script`来指定用于部分更新的脚本。
**结果说明:**
- 如果请求成功,将返回更新操作的状态信息。
#### JavaScript示例代码:
```javascript
const axios = require('axios');
axios.post('http://localhost:9200/my_index/my_type/1/_update', {
script: {
source: "ctx._source.age = params.age",
lang: "painless",
params: {
age: 31
}
}
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
```
**代码解释:**
- 这段JavaScript代码通过Axios库发送HTTP POST请求,实现了对id为1的文档的部分更新,仅更新了age字段。
**结果说明:**
- 如果更新成功,将返回更新后的文档信息。
通过以上示例代码,可以清楚地了解如何使用不同语言来通过HTTP POST请求将文档更新到elasticsearch中。
# 6. 使用RESTful API进行数据查询
数据查询是 elasticsearch 中最常用的操作之一,通过 RESTful API 可以灵活地进行各种查询操作。在本章中,将介绍如何利用 elasticsearch 提供的 API 进行数据查询,包括基本搜索操作、复杂查询 DSL 介绍以及聚合查询操作的实现。
### 6.1 基本搜索操作
在 elasticsearch 中,可以使用简单的字符串进行搜索。以下是一个基本搜索的示例代码,使用 Python 语言:
```python
from elasticsearch import Elasticsearch
# 连接 elasticsearch
es = Elasticsearch()
# 简单搜索
res = es.search(index="my_index", body={"query": {"match": {"title": "elasticsearch"}}})
# 输出搜索结果
for hit in res['hits']['hits']:
print(hit['_source'])
```
**代码说明:**
- 通过 `match` 查询匹配标题为 "elasticsearch" 的文档。
- 输出搜索结果中所有匹配的文档。
**结果说明:**
- 将输出匹配标题为 "elasticsearch" 的文档内容。
### 6.2 复杂查询DSL介绍
elasticsearch 提供了 Query DSL(领域特定语言)用于构建更复杂的查询。以下是一个 DSL 查询的示例代码,使用 Java 语言:
```java
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("content", "elasticsearch"))
.from(0).size(5)
.sort(SortBuilders.fieldSort("timestamp").order(SortOrder.DESC));
SearchResponse searchResponse = client.search(request.source(sourceBuilder), RequestOptions.DEFAULT);
// 处理查询结果
```
**代码说明:**
- 使用 `matchQuery` 构建查询条件,匹配内容为 "elasticsearch" 的文档。
- 设置起始位置、数量和排序规则。
- 处理查询结果。
### 6.3 聚合查询操作的实现
聚合查询是 elasticsearch 中非常强大的功能,可以对数据进行分组、统计等操作。以下是一个聚合查询的示例代码,使用 Go 语言:
```go
package main
import (
"context"
"fmt"
"gopkg.in/olivere/elastic.v7"
)
client, err := elastic.NewClient()
agg := elastic.NewTermsAggregation().Field("category.keyword")
agg.SubAggregation("avg_price", elastic.NewAvgAggregation().Field("price"))
searchResult, err := client.Search("my_index").Aggregation("categories", agg).Do(context.Background())
if err != nil {
fmt.Println("Error:", err)
}
// 处理聚合查询结果
```
**代码说明:**
- 定义按照 `category` 字段分组的 Terms 聚合,并在每个分组下计算 `price` 字段的平均值。
- 执行聚合查询并处理结果。
以上是 elasticsearch 中基本查询操作的示例代码,通过 RESTful API 可以实现各种复杂的数据查询功能。
0
0