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提供了便利的方法供我们操 ...
随机推荐
- 从滑动窗口到YOLO、Transformer:目标检测的技术革新
本文全面回顾了目标检测技术的演进历程,从早期的滑动窗口和特征提取方法到深度学习的兴起,再到YOLO系列和Transformer的创新应用.通过对各阶段技术的深入分析,展现了计算机视觉领域的发展趋势和未 ...
- MySQL运维7-Mycat水平分表
一.水平分表场景 在业务系统中,有一张日志表,业务系统每天都会产生大量的日志数据,单台服务器的数据存储即处理能力是有限的,可以对数据库表进行拆分,这时候就可以使用水平分表的策略 说明1:水平分表,每个 ...
- 江西财经大学第一届程序设计竞赛 H题- 小P的数学问题
题目链接:https://www.nowcoder.com/acm/contest/115/H 解题思路:分块打表!!! 什么是分块打表呢??? 从这道题我们知道我们要找到最多1*e9的阶乘 那循环暴 ...
- flask中使用pyjwt
**pyjwt使用教程: ** https://pyjwt.readthedocs.io/en/stable/ 使用案例 import datetime from flask import Flask ...
- 【C#】【DateTime】获取当前时间的前一天或者后一天方法学习
假期懈怠了一阵子,因为工作环境没有网络,随即记录下当时的问题: 1.关于DateTime.Now(2023/10/07)的前一天的时间(2023/10/06),想要通过ToString转换成字符串后除 ...
- Date、正则表达式练习
Date.正则表达式练习 package com.guoba.date; import java.text.SimpleDateFormat; import java.util.Calendar; i ...
- Web测试基本思路:UI测试、功能测试和兼容性测试
关于网站测试的基本思路,希望对测试小白有所帮助. 一.UI测试 用户界面测试主要是拿待测网页和设计稿进行对比,主要主要以下4点: 1.注重细节: 这点最基本,就是对比是细心.细心再细心. 2.主要整体 ...
- 【李南江】从零玩转TypeScript
前言 老套路肯定是 需要知道TS是干啥用的啦. 1.什么是TypeScript(TS)? TypeScript简称TS TS和JS之间的关系其实就是Less/Sass和CSS之间的关系 就像Less/ ...
- MyBatis 源码解析
本文源码解析针对的是 MyBatis 3.4.4 MyBatis 执行流程 第一阶段 MyBatis 在这个阶段获得 Mapper 的动态代理对象,具体逻辑如下图所示: 其中,Configuratio ...
- bazel 使用 gtest/gmock 报错 Constraints from @bazel_tools//platforms have been removed
问题描述 运行 bazel test 命令,遇到错误:"Constraints from @bazel_tools//platforms have been removed. Please ...