ElasticSearch使用实践(文档操作)
可以使用Docker安装ES和Kibana:
使用docker-compose安装ElasticSearch和Kibana:
version: '3.1'
services:
elasticsearch:
image: elasticsearch:7.13.3
container_name: elasticsearch
privileged: true
environment:
- "cluster.name=elasticsearch"
- "discovery.type=single-node"
- "ES_JAVA_OPTS=-Xms512m -Xmx1096m"
- bootstrap.memory_lock=true
volumes:
- ./es/plugins:/usr/local/dockercompose/elasticsearch/plugins
- ./es/data:/usr/local/dockercompose/elasticsearch/data:rw
- ./es/logs:/usr/local/dockercompose/elasticsearch/logs:rw
ports:
- 9200:9200
- 9300:9300
deploy:
resources:
limits:
cpus: "2"
memory: 1000M
reservations:
memory: 200M
kibana:
image: kibana:7.13.3
container_name: kibana
depends_on:
- elasticsearch
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
I18N_LOCALE: zh-CN
ports:
- 5601:5601
执行:
docker-compose up -d
运行完毕后,访问本机的5601端口就可以看到Kibana的界面
数据基本操作
数据层面的基本概念:
- 索引:一类相似文档的集合,ES将数据存储在一个或多个index中。一个索引有多个分片,索引的数据会以某种方式分散到各个分片上存储
- mapping:定义了索引里的文档有哪些字段,以及字段的类型
- 文档:向ES写入每一条数据都是一个文档,搜索也以文档为单位
- 字段:每个文档都有一个或多个字段,每个字段都有类型
索引管理
定义如下mapping,并创建索引:
PUT books
{
"mappings": {
"properties": {
"book_id": {
"type": "keyword"
},
"name": {
"type": "text"
},
"author": {
"type": "keyword"
},
"intro": {
"type": "text"
}
}
},
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
在 Kibana 中运行上述示例,可以创建 books 索引。books 索引包含 book_id(书本 ID)、name(书本名字)、author(作者)、intro(简介)四个字段
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
这一段指定了books索引还有3个分片和1个副本备份
如果执行DELETE books就可以删除索引
Go语言代码:
package main
const mapping = `{
"mappings": {
"properties": {
"book_id": {
"type": "keyword"
},
"name": {
"type": "text"
},
"author": {
"type": "keyword"
},
"intro": {
"type": "text"
}
}
},
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}`
func main() {
client, err := elastic.NewClient(
elastic.SetURL("http://127.0.0.1:9200"),
elastic.SetSniff(false),
)
if err != nil {
panic(err)
}
ctx := context.Background()
resp, err := client.CreateIndex("books").
BodyString(mapping).Do(ctx)
if err != nil {
log.Fatalln("Error creating the index:", err)
}
if !resp.Acknowledged {
log.Fatalln("Error creating the index:", resp.Index)
}
fmt.Println("Index created:", resp.Index)
}
新建文档
ES提供了两种创建文档的方式,一种是使用Index API索引文档,一种是使用Create API创建文档
使用Index:
PUT books/_doc/1
{
"book_id": "4ee82462",
"name": "深入Linux内核架构",
"author": "Wolfgang Mauerer",
"intro": "内容全面深入,领略linux内核的无限风光。"
}
Go语言代码:
type Book struct {
BookId string `json:"book_id"`
Name string `json:"name"`
Author string `json:"author"`
Intro string `json:"intro"`
}
func main() {
client, err := elastic.NewClient(
elastic.SetURL("http://127.0.0.1:9200"),
elastic.SetSniff(false),
)
if err != nil {
panic(err)
}
// 创建文档数据
book := Book{
BookId: "4ee82462",
Name: "深入Linux内核架构",
Author: "Wolfgang Mauerer",
Intro: "内容全面深入,领略linux内核的无限风光。",
}
ctx := context.Background()
put, err := client.Index().Index("books").Id("1").BodyJson(book).Do(ctx)
if err != nil {
return
}
if err != nil {
panic(err)
}
fmt.Printf("Document id: %s, Index id: %s\n", put.Id, put.Index)
}
使用Create API:
PUT books/_create/2
{
"book_id": "4ee82463",
"name": "时间简史",
"author": "史蒂芬霍金",
"intro": "探索时间和空间核心秘密的引人入胜的故事。"
}
获取文档
可以通过ES的GET API来获取文档内容,获取文档有两种情况,一种是只获取一个文档内容,另一种是同时获取多个文档的内容。获取文档有两种情况,一种是只获取一个文档的内容,另一种是同时获取多个文档的内容。
通过GET API获取单个文档:
GET books/_doc/1
响应:
{
"_index" : "books",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"book_id" : "4ee82462",
"name" : "深入Linux内核架构",
"author" : "Wolfgang Mauerer",
"intro" : "内容全面深入,领略linux内核的无限风光。"
}
}
Go语言代码:
type Book struct {
BookId string `json:"book_id"`
Name string `json:"name"`
Author string `json:"author"`
Intro string `json:"intro"`
}
func main() {
client, err := elastic.NewClient(
elastic.SetURL("http://127.0.0.1:9200"),
elastic.SetSniff(false),
)
if err != nil {
panic(err)
}
ctx := context.Background()
get, err := client.Get().Index("books").Id("1").Do(ctx)
if err != nil {
return
}
if err != nil {
panic(err)
}
if get.Found {
fmt.Printf("document id=%s version=%d index=%s\n",
get.Id, get.Version, get.Index)
}
book := Book{}
data, _ := get.Source.MarshalJSON()
err = json.Unmarshal(data, &book)
if err != nil {
panic(err)
}
fmt.Println(book.Name, book.Author)
}
更新文档
POST books/_update/2
{
"doc": {
"name":"时间简史(视频版)",
"intro": "探索时间和空间核心秘密的引人入胜的视频故事。"
}
}
响应信息:
{
"_index" : "books",
"_type" : "_doc",
"_id" : "2",
"_version" : 2,
"result" : "noop",
"_shards" : {
"total" : 0,
"successful" : 0,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
Go语言代码:
package main
type BookUpdate struct {
Doc struct {
Name string `json:"name"`
Intro string `json:"intro"`
} `json:"doc"`
}
func main() {
client, err := elastic.NewClient(
elastic.SetURL("http://127.0.0.1:9200"),
elastic.SetSniff(false),
)
if err != nil {
panic(err)
}
update := BookUpdate{
Doc: struct {
Name string `json:"name"`
Intro string `json:"intro"`
}{
Name: "时间简史(视频版)",
Intro: "探索时间和空间核心秘密的引人入胜的视频故事。",
},
}
_, err = client.Update().Index("books").
Id("2").Doc(update).Do(context.Background())
if err != nil {
log.Fatalln("Error updating the document:", err)
}
fmt.Printf("Document updated\n")
}
也可以通过索引文档的方式来更新数据,但会先删除数据再写入新的数据,所以无法只更新某些字段
除了用指定ID的方式来更新数据,还可以用update_by_query的方式:
POST books/_update_by_query
{
"query": {
"term": {
"book_id": {
"value": "4ee82462"
}
}
},
"script": {
"source": "ctx._source.name='深入Linux内核架构1'",
"lang": "painless"
}
}
响应信息:
{
"took" : 37,
"timed_out" : false,
"total" : 1,
"updated" : 1,
"deleted" : 0,
"batches" : 1,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0,
"failures" : [ ]
}
Go语言代码:
package main
func main() {
client, err := elastic.NewClient(
elastic.SetURL("http://127.0.0.1:9200"),
elastic.SetSniff(false),
)
if err != nil {
panic(err)
}
ctx := context.Background()
resp, err := client.UpdateByQuery("books").
Query(elastic.NewTermQuery("book_id", "4ee82462")).
Script(elastic.NewScript("ctx._source.name='深入Linux内核架构1'")).
ProceedOnVersionConflict().Do(ctx)
if err != nil {
panic(err)
}
fmt.Println("Documents updated:", resp.Updated)
}
删除文档
DELETE books/_doc/2
Go语言代码:
package main
func main() {
client, err := elastic.NewClient(
elastic.SetURL("http://127.0.0.1:9200"),
elastic.SetSniff(false),
)
if err != nil {
panic(err)
}
ctx := context.Background()
resp, err := client.Delete().Index("books").Id("2").Do(ctx)
if err != nil {
panic(err)
}
fmt.Println("document deleted:", resp.Result)
}
批量操作文档
Bulk API 支持在一次调用中操作不同的索引,使用时可以在 Body 中指定索引也可以在 URI 中指定索引。而且还可以同时支持 4 中类型的操作:
- Index
- Create
- Update
- Delete
Bulk API 的格式是用换行符分隔 JSON 的结构,第一行指定操作类型和元数据(索引、文档id等),紧接着的一行是这个操作的内容(文档数据,如果有的话。像简单的删除就没有。),其格式如下:
POST _bulk
{ "index" : { "_index" : "books", "_id" : "1" } }
{ "book_id": "4ee82462","name": "深入Linux内核架构","author": "Wolfgang Mauerer","intro": "内容全面深入,领略linux内核的无限风光。" }
{ "delete" : { "_index" : "books", "_id" : "2" } }
{ "create" : { "_index" : "books", "_id" : "3" } }
{ "book_id": "4ee82464","name": "深入Linux内核架构第三版","author": "Wolfgang Mauerer","intro": "内容全面深入,再次领略linux内核的无限风光。" }
{ "update" : {"_index" : "books", "_id" : "4"} }
{ "doc" : {"intro" : "书本的内容非常好,值得一看"} }
ElasticSearch使用实践(文档操作)的更多相关文章
- ElasticSearch 基本概念 and 索引操作 and 文档操作 and 批量操作 and 结构化查询 and 过滤查询
基本概念 索引: 类似于MySQL的表.索引的结构为全文搜索作准备,不存储原始的数据. 索引可以做分布式.每一个索引有一个或者多个分片 shard.每一个分片可以有多个副本 replica. 文档: ...
- Elasticsearch (1) 文档操作
本文介绍如何在Elasticsearch中对文档进行操作. 1.检查Elasticsearch及Kibana运行是否正常 在浏览器输入192.168.6.16:9200,有如下输出则说明Elastic ...
- Elasticsearch 7.x文档基本操作(CRUD)
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html 1.添加文档 1.1.指定文档ID PUT ...
- 008-elasticsearch5.4.3【二】ES使用、ES客户端、索引操作【增加、删除】、文档操作【crud】
一.ES使用,以及客户端 1.pom引用 <dependency> <groupId>org.elasticsearch.client</groupId> < ...
- ES入门三部曲:索引操作,映射操作,文档操作
ES入门三部曲:索引操作,映射操作,文档操作 一.索引操作 1.创建索引库 #语法 PUT /索引名称 { "settings": { "属性名": " ...
- 一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
在目前的软件项目中,都会较多的使用到对文档的操作,用于记录和统计相关业务信息.由于系统自身提供了对文档的相关操作,所以在一定程度上极大的简化了软件使用者的工作量. 在.NET项目中如果用户提出了相关文 ...
- jQuery 核心 - noConflict() 方法,jQuery 文档操作 - detach() 方法
原文地址:http://www.w3school.com.cn/jquery/manipulation_detach.asp 实例 使用 noConflict() 方法为 jQuery 变量规定新 ...
- XML文档操作之JAXP下实现
JAXP是java API for xml PRocessing的缩写. 其API可以在javax.xml.parsers 这个包中找到.这个包向用户提供了两个最重要的工厂类,SAXParserFac ...
- jQuery文档操作
jQuery文档操作 1.jq文档结构 var $sup = $('.sup'); $sup.children(); // sup所有的子级们 $sup.parent(); // sup的父级(一个, ...
- 06-jQuery的文档操作
之前js中咱们学习了js的DOM操作,也就是所谓的增删改查DOM操作.通过js的DOM的操作,大家也能发现,大量的繁琐代码实现我们想要的效果.那么jQuery的文档操作的API提供了便利的方法供我们操 ...
随机推荐
- 初识HTML5(2)
在本文中,我将介绍HTML5的超链接标记和表格的相关标记. 超链接标记 超链接是HTML中非常重要的元素,它用于在不同网页或不同部分之间创建链接.以下是一些与超链接相关的标记和属性: 使用<a& ...
- 聊一聊 C# 的线程本地存储TLS到底是什么
一:背景 1. 讲故事 有朋友在后台留言让我说一下C#的 ThreadStatic 线程本地存储是怎么玩的?这么说吧,C#的ThreadStatic是假的,因为C#完全是由CLR(C++)承载的,言外 ...
- 9 个让你的 Python 代码更快的小技巧
哈喽大家好,我是咸鱼 我们经常听到 "Python 太慢了","Python 性能不行"这样的观点.但是,只要掌握一些编程技巧,就能大幅提升 Python 的运 ...
- 如何保证XML正确性
如何保证XML正确性 XML是个盒子,什么都能装,但是装进去的东西正确与否恐怕无法得知.往往我们都人工审核.双人复核保证,但是次数多了难免会出错.那么我们如何保证和避免这种问题出现呢? 那就是XSD, ...
- vue强制横屏
在app.vue中 <template> <div id="app"> <router-view /> </div> </te ...
- 大数据处理黑科技:揭秘PB级数仓GaussDB(DWS) 并行计算技术
摘要:通过这篇文章,我们了解了GaussDB(DWS)并行计算技术的原理以及调优策略.希望广大开发者朋友们能够在实践中尝试该技术,更好地进行性能优化. 随着硬件系统的越来越好,数据库运行的CPU.磁盘 ...
- GaussDB(DWS)性能调优:indexscan导致的性能问题识别与优化
摘要:通常跑批加工场景下,都是大数量做关联操作,通常不建议使用索引.有些时候因为计划误判导致使用索引的可能会导致严重的性能问题.本文从一个典型的索引导致性能的场景重发,剖析此类问题的特征,定位方法和解 ...
- Redis Sentinel 源码:Redis的高可用模型分析
摘要:本文通过对Redis Sentinel源码的理解,详细说明Sentinel的代码实现方式. Redis Sentinel 是Redis提供的高可用模型解决方案.Sentinel可以自动监测一个或 ...
- 百度高德地图行政区域边界GeoJSON数据获取并绘制行政区域
highcharts 是提供地图数据包的:https://www.highcharts.com/docs/maps/map-collection echart矢量地图或者地图绘制矢量图层,GeoJSO ...
- max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
elasticsearch安装后启动时候,遇到此问题 问题翻译过来就是:elasticsearch用户拥有的可创建文件描述的权限太低,至少需要65536: 解决办法: 切换到root用户修改 vim ...