初识ElasticSearch

初识ElasticSearch

ElasticSearch后面简称ES,本篇文章基于ES:7.4.2

官网文档

一、ES介绍

1. 用处

You know, for search (and analysis)

Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack. Logstash and Beats facilitate collecting, aggregating, and enriching your data and storing it in Elasticsearch. Kibana enables you to interactively explore, visualize, and share insights into your data and manage and monitor the stack. Elasticsearch is where the indexing, search, and analysis magic happen.

Elasticsearch provides real-time search and analytics for all types of data. Whether you have structured or unstructured text, numerical data, or geospatial data, Elasticsearch can efficiently store and index it in a way that supports fast searches. You can go far beyond simple data retrieval and aggregate information to discover trends and patterns in your data. And as your data and query volume grows, the distributed nature of Elasticsearch enables your deployment to grow seamlessly right along with it.

Elasticsearch is a distributed document store.

总结来说,ES是一个分布式搜索和分析引擎,可以提供快速的数据实时搜索和分析能力,同时也是一个分布式文档存储。

2. 术语

2.1. cluster(集群)

集群由一个或多个共享相同集群名称的节点组成。每个集群都有一个单独的主节点,这个节点由集群自动选择,如果当前的主节点失败,可以替换它。

2.2. document(文档)

文档是存储在 Elasticsearch 的 JSON 文档。它就像关系数据库里一行记录。每个文档都存储在一个索引中,并具有一个类型和一个 id。

2.3. field(字段)

文档包含字段或键值对的列表。这个值可以是一个简单的(标量)值(如字符串、整数、日期) ,也可以是一个嵌套结构(如数组或对象)。字段类似于关系数据库中表中的列。

2.4. id(身份标识)

文档的 id 标识文档。文档的index/id 必须是唯一的。如果没有提供 id,那么它将自动生成。

2.5. index(索引)

索引就像关系数据库中的一张表。

2.6. mapping(映射)

A mapping is like a schema definition in a relational database. Each index has a mapping, which defines a type, plus a number of index-wide settings.

想要理解这段话,可以先看一下下面两篇文章,简要的介绍了一下schema的概念,第二篇是第一篇的翻译

What is a Database Schema?

数据库中的Schema是什么?

结论:MySQL官方文档指出,从概念上讲,模式是一组相互关联的数据库对象,如表,表列,列的数据类型,索引,外键等等。但是从物理层面上来说,模式与数据库是同义的。

我的理解:针对MySQL来说,schema记录了数据库的规则;database记录的则是数据本身。这两则在物理层面又是同义的,都是存储。所以ES中mapping记录的是index的规则。

2.7. type(类型)

A type used to represent the type of document, e.g. an email, a user, or a tweet. Types are deprecated and are in the process of being removed. See Removal of mapping types.

type用于定义document的类型

但这个概念正在被删除中.....

2.8. 总结

刚开始学ES,对ES的概念有点模糊,这里我们和关系型数据库的概念进行比对学习

Relational DB -> Schemas  -> Tables  -> Rows -> Columns
Elasticsearch -> Mappings -> Indices -> Documents -> Fields

二、启动ES&KB

这里默认你已经装好了docker

docker pull blacktop/elasticsearch:7.4
docker tag blacktop/elasticsearch:7.4 es7.4
docker run -d --name es -p 9200:9200 es:7.4


docker pull blacktop/kibana:7.4
docker tag blacktop/kibana:7.4 kb:7.4
docker run --init -d --name kb -e elasticsearch.hosts=http://192.168.1.101:9200 -p 5601:5601 kb:7.4			# 192.168.1.101:9200根据情况变化,不要使用localhost/127.0.0.1
docker logs kb			 # 查看kb是否有连接上es

三、CRUD

使用olivere/elastic连接elasticsearch时,发现连接地址明明输入的时候是公网地址,但是连接时会自动转换成内网地址或者docker中的ip地址,导致服务连接不上。

解决方案:

func GetESClient() *elastic.Client {
    client, err := elastic.NewClient(
      elastic.SetURL("http://127.0.0.1:9200"),
      // 将sniff设置为false后,便不会自动转换地址
      elastic.SetSniff(false),
    )
    if err != nil {
      log.Fatalln("start es err=", err)
      return nil
    }
    return client
}

1. Kibana操作ES

// 添加mapping结构
PUT /books
{
  "mappings": {
    "properties": {
      "book_id":    { "type": "integer" },
      "book_name":    { "type": "text" },  
      "book_intr":  { "type": "text"  }, 
      "book_price1":   { "type": "float"},  
      "book_price2":   { "type": "float"},  
      "book_author":   { "type": "keyword"},
      "book_date":   { "type": "date"},
      "book_kind":   { "type": "integer"},
      "book_press":   { "type": "keyword"}
    }
  }
}

// 获取mapping结构
GET /books/_mapping

// 获取books索引中文档的个数
GET /books/_count

// 搜索books索引默认前10条数据
GET /books/_search

// 删除books索引
DELETE /books

2. Go-ES批量插入

// 获取ES的客户端
client := config.GetESClient()

// 批量插入的容器
bulk := client.Bulk()
for _, book := range bookList {
    req := elastic.NewBulkIndexRequest()
    req.Index("books").Id(strconv.Itoa(book.BookID)).Doc(book)
  
  	// 添加进容器中...
    bulk.Add(req)
}

// 执行批量添加操作
resp, err := bulk.Do(ctx)
if err != nil {
  	fmt.Println(err)
} else {
  	fmt.Println(resp)
}

3. Gin展示ES数据

// gin的组件
func LoadBooks(ctx *gin.Context) {
	resp, err := config.GetESClient().Search().Index("books").Do(ctx)
	if err != nil {
		ctx.JSON(500, gin.H{
			"error": err,
		})
	} else {
		ctx.JSON(200, gin.H{
			"result": Map2Book(resp),
		})
	}
}

// ES搜索结果转化为对应的结构体
func Map2Book(resp *elastic.SearchResult) []*model.Books {
	books := make([]*model.Books, 0)
	for _, v := range resp.Each(reflect.TypeOf(&model.Books{})) {
		books = append(books, v.(*model.Books))
	}
	return books
}

func main() {
	router := gin.Default()
	g := router.Group("/books")
	initRouter(g)
	err := router.Run(":8080")
	if err != nil {
		panic(err)
	}
}

func initRouter(g *gin.RouterGroup) {
	g.Handle("GET", "", gin_func.LoadBooks)
}

4. 精准查询

使用term精准查询

Kibana

GET /books/_search
{
  "query":{
    "term": {
      "book_author": "罗会波"
    }
  }
}

Go-ES

func LoadBooksByAuthor(ctx *gin.Context) {
	press, _ := ctx.Params.Get("author")
	termQuery := elastic.NewTermQuery("book_author", press)
	resp, err := config.GetESClient().Search().Query(termQuery).Index("books").Do(ctx)
	if err != nil {
		ctx.JSON(500, gin.H{
			"error": err,
		})
	} else {
		ctx.JSON(200, gin.H{
			"result": Map2Book(resp),
		})
	}
}

5. 全文匹配&分词器

使用match进行全文匹配

GET /books/_search
{
  "query":{
    "match": {
      "book_name": "程序教程"
    }
  }
}

// 安装了ik分词器之后,对中文还是很友好的!
POST _analyze 
{
  "analyzer": "ik_smart",
  "text":"程序设计java"
}

{
  "tokens" : [
    {
      "token" : "程序设计",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "java",
      "start_offset" : 4,
      "end_offset" : 8,
      "type" : "ENGLISH",
      "position" : 1
    }
  ]
}

5.1. 如何安装ik分词器

这玩意一定要和ES的版本一致!!!!

这玩意一定要和ES的版本一致!!!!

这玩意一定要和ES的版本一致!!!!

我的ES是7.4.2的,所以下载过来的ik也得是7.4.2的

https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip

下载过来之后,解压,随后cp到es的容器中即可

docker cp /Users/ch/study/ik es:/usr/share/elasticsearch/plugins

重启es容器(如果ik和es的版本不一致,这里会启动失败.....启动失败以后建议删除容器,重新run一下ES的镜像)

docker restart es

校验ik分词器是否安装成功,可以用上面下面这条命了在kibana上运行一下

POST _analyze 
{
  "analyzer": "ik_smart",
  "text":"程序设计java"
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×