Golang實戰ES
- 一、ES的安裝
- 下載elasticSearch7.7.0
- docker-compose啟動elasticSearch7.7.0
- 安裝中文分詞器IK
- 注意事項
- 二、ES的簡單的應用
- 查詢
- 簡單查詢
- 復合條件查詢
- 三、ES的在go中實戰專案運用
- 安裝
- 連接
- 查詢索引
- 添加
- 查詢
- 更新
- 洗掉
- 回傳搜索詞高亮處理
一、ES的安裝
下載elasticSearch7.7.0
docker pull elasticsearch:7.7.0 //下拉鏡像
docker images //查看鏡像
//創建所需檔案
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
echo "http.host: 0.0.0.0">>/mydata/elasticsearch/config/elasticsearch.yml
//檔案夾賦權
chmod -R 777 elasticsearch/
//命令啟動
docker run --name elasticsearch -p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.7.0
//引數說明
--name elasticsearch:將容器命名為 elasticsearch
-p 9200:9200:將容器的9200埠映射到宿主機9200埠
-p 9300:9300:將容器的9300埠映射到宿主機9300埠,目的是集群互相通信
-e "discovery.type=single-node":單例模式
-e ES_JAVA_OPTS="-Xms64m -Xmx128m":配置記憶體大小
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:將組態檔掛載到宿主機
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data:將資料檔案夾掛載到宿主機
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins:將插件目錄掛載到宿主機(需重啟)
-d elasticsearch:7.7.0:后臺運行容器,并回傳容器ID
docker-compose啟動elasticSearch7.7.0
//docker-compose啟動
version: '2'
services:
elasticsearch:
container_name: elasticsearch
image: elasticsearch:7.7.0
ports:
- "9200:9200"
volumes:
- /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- /mydata/elasticsearch/data:/usr/share/elasticsearch/data
- /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins
environment:
- "ES_JAVA_OPTS=-Xms64m -Xmx128m"
- "discovery.type=single-node"
- "COMPOSE_PROJECT_NAME=elasticsearch-server"
restart: always
//查看容器
docker ps -a
//驗證是否成功
curl http://192.168.0.50:9200/
//回傳資訊
{
"name" : "550eca5cf3b2",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "1mP9IJU3TUy_C2DZMfKGBg",
"version" : {
"number" : "7.7.0",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "81a1e9eda8e6183f5237786246f6dced26a10eaf",
"build_date" : "2020-05-12T02:01:37.602180Z",
"build_snapshot" : false,
"lucene_version" : "8.5.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
//Docker啟動容器自啟
docker update elasticsearch --restart=always
安裝中文分詞器IK
1.在線安裝
//進入容器
docker exec -it elasticsearch /bin/bash
//在線下載并安裝
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.5.4/elasticsearch-analysis-ik-6.5.4.zip
//進入plugins可以看到IK分詞器已經安裝成功
目錄中有analysis-ik安裝成功
2.離線安裝
//將IK分詞器上傳到/tmp目錄中elasticsearch-analysis-ik-6.5.4.zip
//將壓縮包移動到容器里面
docker cp /tmp/elasticsearch-analysis-ik-6.5.4.zip elasticsearch:/usr/share/elasticsearch/plugins
//進入容器
docker exec -it elasticsearch /bin/bash
//創建目錄
mkdir /usr/share/elasticsearch/plugins/ik
//將檔案壓縮包移動到ik中
mv /usr/share/elasticsearch/plugins/elasticsearch-analysis-ik-6.5.4.zip /usr/share/elasticsearch/plugins/ik
//進入目錄
cd /usr/share/elasticsearch/plugins/ik
//解壓
unzip elasticsearch-analysis-ik-6.5.4.zip
//洗掉壓縮包
rm -rf elasticsearch-analysis-ik-6.5.4.zip
//退出并重啟鏡像
exit
docker restart elasticsearch
注意事項
*** 注意 安裝中文分詞器版本一定要和ES的版本號對應,不然會報錯,
報錯資訊如下:
Exception in thread "main" java.lang.IllegalArgumentException: Plugin [analysis-ik] was built for Elasticsearch version 7.0.0 but version 7.7.0 is running
at org.elasticsearch.plugins.PluginsService.verifyCompatibility(PluginsService.java:346)
at org.elasticsearch.plugins.InstallPluginCommand.loadPluginInfo(InstallPluginCommand.java:814)
at org.elasticsearch.plugins.InstallPluginCommand.installPlugin(InstallPluginCommand.java:869)
at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:254)
at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:224)
at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127)
at org.elasticsearch.cli.MultiCommand.execute(MultiCommand.java:91)
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127)
at org.elasticsearch.cli.Command.main(Command.java:90)
at org.elasticsearch.plugins.PluginCli.main(PluginCli.java:47)
查看對應IK版本號:https://github.com/medcl/elasticsearch-analysis-ik/releases
安裝完成重啟ES
docker restart elasticsearch
IK分詞使用
請求地址POST:http://127.0.0.1/_analyze?pretty
{
"analyzer": "ik_smart",
"text": "中華人民共和國國歌"
}
//回傳內容
{
"tokens": [
{
"token": "中華人民共和國",
"start_offset": 0,
"end_offset": 7,
"type": "CN_WORD",
"position": 0
},
{
"token": "國歌",
"start_offset": 7,
"end_offset": 9,
"type": "CN_WORD",
"position": 1
}
]
}
ik_max_word:最細粒度的拆分
ik_smart: 最粗粒度的拆分
二、ES的簡單的應用
查詢
簡單查詢
Query Context 處理判斷檔案是否滿足查詢條件以外,ES還會計算一個_score 來標識匹配程度,判斷目標檔案與查詢條件匹配的有多好, 常用查詢 針對文本型別資料 欄位級別的查詢 針對結構化資料,如數字,日期,
Post請求 127.0.0.1/book/_search
//模糊查詢
{
"query":{
"match":{
"author":"瓦力"
}
}
}
//準確查詢
{
"query":{
"match_parase":{
"author":"瓦力"
}
}
}
//多欄位的匹配查詢(查詢autor和title包含瓦力的)
{
"query":{
"multi_match":{
"query":"瓦力",
"fields":["author", "title"]
}
}
}
//查詢瓦力和很好或則是python
{
"query":{
"query_string":{
"query":"(瓦力 AND 很好)OR python",
}
}
}
//查詢瓦力和很好或則是python(在author和title欄位中)
{
"query":{
"query_string":{
"query":"(瓦力 AND 很好)OR python",
"fields":["author", "title"]
}
}
}
//欄位級別的查詢,查詢字數等于1000的圖書
{
"query":{
"term":{
"word_count": 1000
}
}
}
//欄位級別的查詢,查詢字數在1000-2000的圖書有哪些,
//now表示現在時間,gte表示大于等于,gt表示大于
{
"query":{
"range":{
"word_count":{
"gte":1000,
"lte":2000
}
}
}
}
Filter Context 子條件查詢 在查詢程序中,只判斷該檔案是否滿足條件,只有Yes或No 進行資料過濾,會加到快取中,比query要快
//查詢字數在一千字的書籍
{
"query": {
"bool": {
"filter": {
"term": {
"word_count": 1000
}
}
}
}
}
復合條件查詢
//POST 127.0.0.1/_search
//全文查詢,但是給出的評分不是一樣的
{
"query": {
"match": {
"title": "ElasticSeach"
}
}
}
//固定評分查詢,結果評分全部是1,不支持match
{
"query": {
"constant_score": {
"filter": {
"match": {
"title": "ElasticSearch"
}
},
"boost": 2 //指定分數查詢,
}
}
}
//must必須查詢條件
{
"query": {
bool": {
"should": [
{
"match": {
"author": "瓦力"
}
},
{
"match":{
"title": "ElasticSearch"
}
}
],
"filter": [
{
"term":{
"word_count": 1000
}
}
]
}
}
}
}
//must_not.不滿足條件,篩選處作者沒有瓦力的條件
{
"query": {
"must_not": {
"term": {
"author": "瓦力"
}
}
}
}
三、ES的在go中實戰專案運用
安裝
1.根據版本安裝依賴(注意go mod 安裝和直接安裝方法不一樣,下面是go mod 安裝)
"github.com/olivere/elastic/v7"
連接
//連接客戶端
client, err := elastic.NewClient(elastic.SetURL(esUrl), elastic.SetSniff(false))
if err != nil {
// Handle error
fmt.Println("出錯了")
panic(err)
}
// Ping the Elasticsearch server to get e.g. the version number
// ping通服務端,并獲得服務端的es版本,本實體的es版本為version 7.6.1
info, code, err := client.Ping(esUrl).Do(ctx)
if err != nil {
// Handle error
panic(err)
}
fmt.Println("開始列印版本號")
fmt.Printf("Elasticsearch returned with code>: %d and version %s\n", code, info.Version.Number)
// 獲取版本號的直接API
esVersion, err := client.ElasticsearchVersion(esUrl)
if err != nil {
panic(err)
}
fmt.Printf("es的版本為%s\n", esVersion)
查詢索引
//連接客戶端
client, err := elastic.NewClient(elastic.SetURL(esUrl), elastic.SetSniff(false))
if err != nil {
// Handle error
fmt.Println("出錯了")
panic(err)
}
// Ping the Elasticsearch server to get e.g. the version number
// ping通服務端,并獲得服務端的es版本,本實體的es版本為version 7.6.1
info, code, err := client.Ping(esUrl).Do(ctx)
if err != nil {
// Handle error
panic(err)
}
fmt.Println("開始列印版本號")
fmt.Printf("Elasticsearch returned with code>: %d and version %s\n", code, info.Version.Number)
// 獲取版本號的直接API
esVersion, err := client.ElasticsearchVersion(esUrl)
if err != nil {
panic(err)
}
fmt.Printf("es的版本為%s\n", esVersion)
添加
//連接客戶端
client, err := elastic.NewClient(elastic.SetURL(esUrl), elastic.SetSniff(false))
if err != nil {
// Handle error
fmt.Println("出錯了")
panic(err)
}
// Ping the Elasticsearch server to get e.g. the version number
// ping通服務端,并獲得服務端的es版本,本實體的es版本為version 7.6.1
info, code, err := client.Ping(esUrl).Do(ctx)
if err != nil {
// Handle error
panic(err)
}
fmt.Println("開始列印版本號")
fmt.Printf("Elasticsearch returned with code>: %d and version %s\n", code, info.Version.Number)
// 獲取版本號的直接API
esVersion, err := client.ElasticsearchVersion(esUrl)
if err != nil {
panic(err)
}
fmt.Printf("es的版本為%s\n", esVersion)
查詢
5.查詢
get1, err := client.Get().Index("user").Id("1").Do(ctx)
if err != nil{
panic(err)
}
if get1.Found{
fmt.Printf("Got document %s in version %d from index %s, type %s\n", get1.Id, get1.Version, get1.Index, get1.Type)
}
//將保存的內容保存到磁盤
_, err = client.Flush().Index("user").Do(ctx)
if err != nil {
panic(err)
}
// 按"term"搜索Search with a term query
termQuery := elastic.NewTermQuery("name", "mike")
searchResult, err := client.Search().
Index("user"). // 搜索的索引"user"
Query(termQuery). // specify the query
Sort("age", true). //按欄位"age"排序,升序排列
From(0).Size(10). // 分頁,單頁顯示10條
Pretty(true). // pretty print request and response JSON以json的形式回傳資訊
Do(ctx) // 執行
if err != nil {
// Handle error
panic(err)
}
fmt.Printf("Query took %d milliseconds\n", searchResult.TookInMillis)// 按"term"搜索Search with a term query
termQuery := elastic.NewTermQuery("name", "mike")
searchResult, err := client.Search().
Index("user"). // 搜索的索引"user"
Query(termQuery). // specify the query
Sort("age", true). //按欄位"age"排序,升序排列
From(0).Size(10). // 分頁,單頁顯示10條
Pretty(true). // pretty print request and response JSON以json的形式回傳資訊
Do(ctx) // 執行
if err != nil {
// Handle error
panic(err)
}
fmt.Printf("Query took %d milliseconds\n", searchResult.TookInMillis)
var user User
//Each是一個簡便函式,此函式忽略了錯誤輸出
for _, item1 := range searchResult.Each(reflect.TypeOf(user)) {
if u, ok := item1.(User); ok {
fmt.Printf("Person by %s,age:%d,married:%t,Sex:%s\n", u.Name, u.Age, u.Married,u.Sex) //Person by bob,age:23,married:false,Sex:male
}
// 搜索檔案方法2
// 使用hits,獲得更詳細的輸出結果
if searchResult.Hits.TotalHits.Value >0{
fmt.Printf("找到的資料總數是 %d \n", searchResult.Hits.TotalHits.Value)
for _,hits := range searchResult.Hits.Hits{
u :=User{}
err := json.Unmarshal([]byte(hits.Source), &u)
if err != nil{
fmt.Println("反序列化失敗",err)
}
fmt.Printf("User by %s,age:%d,married:%t,Sex:%s\n", u.Name, u.Age, u.Married,u.Sex)
}
}else {
fmt.Println("沒有搜到用戶")
}
更新
// 更新檔案 update
update, err := client.Update().Index("user").Id("1").
Script(elastic.NewScriptInline("ctx._source.age += params.num").Lang("painless").Param("num", 1)).
//Upsert(map[string]interface{}{"created": "2020-06-17"}). // 插入未初始化的欄位value
Do(ctx)
if err != nil {
// Handle error
panic(err)
}
fmt.Printf("New version of user %q is now %d\n", update.Id, update.Version)
// 更新方法2
update,err := client.Update().Index("user").Id("1").
Script(elastic.NewScriptInline("ctx._source.created=params.date").Lang("painless").Param("date","2020-06-17")).
Do(ctx)
termQuery := elastic.NewTermQuery("name", "bob")
update,err = client.UpdateByQuery("user").Query(termQuery).
Script(elastic.NewScriptInline("ctx._source.age += params.num").Lang("painless").Param("num", 1)).
Do(ctx)
if err != nil{
panic(err)
}
fmt.Printf("New version of user %q is now %d\n", update.Id, update.Version)
fmt.Println(update)
洗掉
//洗掉檔案
termQuery := elastic.NewTermQuery("name", "mike")
_, err = client.DeleteByQuery().Index("user"). // search in index "user"
Query(termQuery). // specify the query
Do(ctx)
if err != nil {
// Handle error
panic(err)
}
回傳搜索詞高亮處理
func QueryHeight(search dto.SearchActileDto,client *elastic.Client) (hightmap []bo.SearchActileBo,err error){
var data []bo.SearchActileBo
textFild:=elastic.NewHighlighterField("content")
//idFild:=elastic.NewHighlighterField("id")
//fild.PreTags("<em>")
//fild.PostTags("</em>")
titleFild:=elastic.NewHighlighterField("title")
titleFild.FragmentSize(350)
higthFild :=elastic.NewHighlight()
higthFild.Fields(titleFild)
higthFild.Fields(textFild)
//higthFild.Fields(idFild)
//兩個里面必須有
//query :=elastic.NewBoolQuery().Must(elastic.NewMatchPhraseQuery("title","css"),elastic.NewMatchPhraseQuery("text","css"))
query :=elastic.NewBoolQuery().Should(elastic.NewMatchPhraseQuery("title",search.SearchWord),elastic.NewMatchPhraseQuery("content",search.SearchWord))
res, err := client.Search("article").Query(query).Highlight(higthFild).Size(int(search.Size)).From(int((search.Current - 1) * search.Size)).Do(context.Background())
if err != nil {
return nil,err
}
//fmt.Println(res.Hits.Hits)
for _, hit := range res.Hits.Hits {
aa :=hit.Highlight
var search bo.SearchActileBo
search.ContentId = hit.Id
var qq dto.Article
json.Unmarshal(hit.Source,&qq)
search.CreatTime = fmt.Sprintf("%v",qq.CreateTime)
search.CreateID = qq.CreateBy
if aa["title"] == nil{
search.Title=qq.Title
}else{
search.Title=aa["title"][0]
}
if aa["content"] == nil{
search.Content=qq.Content
}else{
search.Content = aa["content"][0]
}
data = append(data, search)
}
return data,nil
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/304048.html
標籤:區塊鏈
