主頁 > 後端開發 > ElasticSearch系列01

ElasticSearch系列01

2023-02-18 07:19:34 後端開發

系列內容

  • elasticsearch 概述
  • elasticsearch 安裝
  • elasticsearch 查詢
  • 客戶端api使用

1. elasticsearch 概述

1.1 簡介

官網: https://www.elastic.co/

Elasticsearch (簡稱ES)是一個分布式、RESTful 風格的搜索和資料分析引擎,能夠解決不斷涌現出的各種用例,

查詢和分析

  • 可以自定義搜索方式: 通過 Elasticsearch,您能夠執行及合并多種型別的搜索(結構化資料、非結構化資料、地理位置、指標),搜索方式隨心而變,先從一個簡單的問題出發,試試看能夠從中發現些什么,
  • 分析大規模資料: 找到與查詢最匹配的 10 個檔案并不困難,但如果面對的是十億行日志,又該如何解讀呢?Elasticsearch 聚合讓您能夠從大處著眼,探索資料的趨勢和規律,

查詢速度

  • 近實時搜索(資料1s之內可見)
  • 通過有限狀態轉換器實作了用于全文檢索的倒排索引,實作了用于存盤數值資料和地理位置資料的 BKD 樹,以及用于分析的列存盤,
  • 每個資料都被編入了索引,因此您再也不用因為某些資料沒有索引而煩心,您可以用快到令人驚嘆的速度使用和訪問您的所有資料,

可擴展性

  • 無論 Elasticsearch 是在一個節點上運行,還是在一個包含 300 個節點的集群上運行,您都能夠以相同的方式與 Elasticsearch 進行通信,
  • 它能夠水平擴展,每秒鐘可處理海量事件,同時能夠自動管理索引和查詢在集群中的分布方式,以實作極其流暢的操作,

內容相關度

  • 基于各項元素(從詞頻或新近度到熱門度等)對搜索結果進行排序,將這些內容與功能進行混搭,以優化向用戶顯示結果的方式,

    而且,由于我們的大部分用戶都是真實的人,Elasticsearch 具備齊全功能,可以處理包括各種復雜情況(例如拼寫錯誤)在內的人為錯誤,

彈性設計

  • 硬體故障,網路分割,Elasticsearch 為您檢測這些故障并確保您的集群(和資料)的安全性和可用性,通過跨集群復制功能,輔助集群可以作為熱備份隨時投入使用,Elasticsearch 運行在一個分布式的環境中,從設計之初就考慮到了這一點,目的只有一個,讓您永遠高枕無憂

創始人:Shay Banon(謝巴農)

image

搜索引擎典型應用場景:

image

image

1.2 全文搜索引擎

Google,百度類的網站搜索,它們都是根據網頁中的關鍵字生成索引,我們在搜索的時候輸入關鍵字,它們會將該關鍵字即索引匹配到的所有網頁回傳;還有常見的專案中應用日志的搜索等等,對于這些非結構化的資料文本,關系型資料庫搜索不是能很好的支持,

一般傳統資料庫,全文檢索都實作的很雞肋,因為一般也沒人用資料庫存文本欄位,進行全文檢索需要掃描整個表,如果資料量大的話即使對SQL的語法優化,也收效甚微,建立了索引,但是維護起來也很麻煩,對于 insert 和 update 操作都會重新構建索引,

這里說到的全文搜索引擎指的是目前廣泛應用的主流搜索引擎,它的作業原理是計算機索引程式通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現的次數和位置,當用戶查詢時,檢索程式就根據事先建立的索引進行查找,并將查找的結果反饋給用戶的檢索方式,這個程序類似于通過字典中的檢索字表查字的程序,

1.3 lucene介紹

? Lucene是Apache軟體基金會Jakarta專案組的一個子專案,提供了一個簡單卻強大的應用程式介面,能夠做全文索引和搜尋,在Java開發環境里Lucene是一個成熟的免費開源工具,就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java資訊檢索程式庫,但Lucene只是一個提供全文搜索功能類別庫的核心工具包,而真正使用它還需要一個完善的服務框架搭建起來進行應用,

? 目前市面上流行的搜索引擎軟體,主流的就兩款:Elasticsearch和Solr,這兩款都是基于Lucene搭建的,可以獨立部署啟動的搜索引擎服務軟體,由于內核相同,所以兩者除了服務器安裝、部署、管理、集群以外,對于資料的操作 修改、添加、保存、查詢等等都十分類似,

1.4 倒排索引

image

倒排索引步驟:

  • 資料根據詞條進行分詞,同時記錄檔案索引位置
  • 將詞條相同的資料化進行合并
  • 對詞條進行排序

搜索程序:

先將搜索詞語進行分詞,分詞后再倒排索引串列查詢檔案位置(docId),根據docId查詢檔案資料,

1.5 elasticsearch、solr對比

image

image

image

image

ElasticSearch vs Solr 總結

  • es基本是開箱即用,非常簡單,Solr安裝略微復雜,
  • Solr 利用 Zookeeper 進行分布式管理,而 Elasticsearch 自身帶有分布式協調管理功能,
  • Solr 支持更多格式的資料,比如JSON、XML、CSV,而 Elasticsearch 僅支持json檔案格式,
  • Solr 是傳統搜索應用的有力解決方案,但 Elasticsearch 更適用于新興的實時搜索應用,

現在很多互聯網應用都是要求實時搜索的,所以我們選擇了elasticsearch,

2. elasticsearch 安裝

2.1 下載軟體

https://www.elastic.co/cn/downloads/past-releases#elasticsearch

選擇7.8版本即可,其它elastic stack也可以在這里下載,

image
下載對應作業系統平臺的版本:

image

2.2 windows環境安裝

解壓elasticsearch-7.8.0-windows-x86_64.zip,目錄結構:

image

目錄 說明
bin 可執行腳本目錄
config 配置目錄
jdk 內置jdk目錄
lib 類別庫
logs 日志目錄
modules 模塊目錄
plugins 插件目錄

解壓完成后進入bin目錄,雙擊運行elasticsearch.bat

image

測驗訪問: http://localhost:9200/

image

2.3 linux環境安裝

將下載好的elasticsearch-7.8.0-linux-x86_64.tar.gz上傳至服務器并解壓,先將jdk環境搭建好,jdk環境配置略,

image

2.3.1 前提條件

elasticsearch不能直接通過root用戶啟動,所以要先創建一個普通用戶,

#創建用戶
useradd es;
#設定密碼
passwd es;

給普通用戶授權:

chown -R es /opt/es

給用戶設定sudo權限:

#使用root用戶執行
visudo
#在root    ALL=(ALL)       ALL下面新增
es      ALL=(ALL)       ALL

image

普通用戶在啟動elasticsearch時會出現下面錯誤:

image

解決辦法:

普通用戶打開檔案最大數限制修改

#編輯limits.conf檔案
vi /etc/security/limits.conf

#添加以下內容
* soft nofile 65536 
* hard nofile 131072 
* soft nproc 2048 
* hard nproc 4096

普通用戶啟動執行緒數限制

# Centos6 
vi /etc/security/limits.d/90‐nproc.conf
# Centos7
vi /etc/security/limits.d/20‐nproc.conf

#添加以下內容
* soft nproc 4096

普通用戶增大虛擬記憶體

vi /etc/sysctl.conf
#添加以下內容:
vm.max_map_count=262144

#保存后執行sysctl -p讓配置生效
sysctl -p

全部步驟完成后需要重新打開終端,重新登入,

2.3.2 修改配置

切換普通用戶(es)登入,進入到${解壓目錄}/config目錄下,修改elasticsearch.yml組態檔:

#集群名稱
cluster.name: my-application
#節點名稱
node.name: node-1
#資料檔案目錄
path.data: ./data
#日志檔案目錄
path.logs: ./logs
#運行訪問的網路,0.0.0.0表示任意ip都匹配,這樣可以遠程訪問
network.host: 0.0.0.0
#http rest服務埠
http.port: 9200
#集群初始master選舉節點
cluster.initial_master_nodes: ["node-1"]

2.3.3 啟動elasticsearch

#進入到bin目錄(注意,不能使用root賬號啟動)
./elasticsearch -d

image

瀏覽器測驗訪問:

image

2.4 docker安裝

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -d --name elasticsearch docker.elastic.co/elasticsearch/elasticsearch:7.8.0

2.5 kibana安裝

elasticsearch服務是一個restful風格的http服務,我們可以采用postman作為客戶端來進行操作,elastic stack官方也給我們提供了kibana來進行客戶端操作,這個相比postman要友好一點,因為里面有些自動補全的代碼提示,

下載地址: https://www.elastic.co/cn/downloads/past-releases/kibana-7-8-0

image

上傳tar并解壓檔案:

image

進入到config目錄,修改kibana.yml檔案:

#服務埠
server.port: 5601
#運行訪問的IP設定,0.0.0.0可以遠程訪問
server.host: "0.0.0.0"

進入bin目錄,后臺啟動kibana:

nohup ./kibana &

image

開始訪問:http://192.168.6.100:5601/

image

image

image

2.6 ik分詞器安裝

下載地址: https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip

進入到${es安裝目錄}/plugins目錄,新建ik目錄

image

image

#在ik目錄下解壓elasticsearch-analysis-ik-7.8.0.zip檔案
unzip elasticsearch-analysis-ik-7.8.0.zip
#洗掉zip檔案
rm -f elasticsearch-analysis-ik-7.8.0.zip

重啟es:

image

測試分詞器:

POST _analyze
{
  "analyzer": "ik_smart",
  "text": "我是中國人"
}

image

3. elasticsearch核心概念

3.1 es對照資料庫

image

3.2 索引(Index)

一個索引就是一個擁有幾分相似特征的檔案的集合,比如說,你可以有一個客戶資料的索引,另一個產品目錄的索引,還有一個訂單資料的索引,一個索引由一個名字來標識(必須全部是小寫字母),并且當我們要對這個索引中的檔案進行索引、搜索、更新和洗掉的時候,都要使用到這個名字,在一個集群中,可以定義任意多的索引,

能搜索的資料必須索引,這樣的好處是可以提高查詢速度,比如:新華字典前面的目錄就是索引的意思,目錄可以提高查詢速度,

Elasticsearch索引的精髓:一切設計都是為了提高搜索的性能,

3.3 型別(Type)

在一個索引中,你可以定義一種或多種型別,

一個型別是你的索引的一個邏輯上的分類/磁區,其語意完全由你來定,通常,會為具有一組共同欄位的檔案定義一個型別,不同的版本,型別發生了不同的變化

版本 Type
5.x 支持多種type
6.x 只能有一種type
7.x 默認不再支持自定義索引型別(默認型別為:_doc)

3.4 檔案(Document)

一個檔案是一個可被索引的基礎資訊單元,也就是一條資料

比如:你可以擁有某一個客戶的檔案,某一個產品的一個檔案,當然,也可以擁有某個訂單的一個檔案,檔案以JSON(Javascript Object Notation)格式來表示,而JSON是一個到處存在的互聯網資料互動格式,

在一個index/type里面,你可以存盤任意多的檔案,

3.5 欄位(Field)

相當于是資料表的欄位,對檔案資料根據不同屬性進行的分類標識,

3.6 映射(Mapping)

mapping是處理資料的方式和規則方面做一些限制,如:某個欄位的資料型別、默認值、分析器、是否被索引等等,這些都是映射里面可以設定的,其它就是處理ES里面資料的一些使用規則設定也叫做映射,按著最優規則處理資料對性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能對性能更好,

4. elasticsearch基本操作

參考檔案: https://www.elastic.co/guide/en/elasticsearch/reference/7.8/index.html

image

4.1 分詞器

官方提供的分詞器有這么幾種: Standard、Letter、Lowercase、Whitespace、UAX URL Email、Classic、Thai等,中文分詞器可以使用第三方的比如IK分詞器,前面我們已經安裝過了,

IK分詞器核心配置:

  • main.dic:單詞詞典
  • stopword.dic: 停用詞,這里只記錄了英文的一部分單詞,比如: ?a、an、and、are、as、at、be、but、by等,

image

IK分詞器:

POST _analyze
{
  "analyzer": "ik_smart",
  "text": "我是中國人"
}

結果:
{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中國人",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    }
  ]
}

POST _analyze
{
  "analyzer": "ik_max_word",
  "text": "我是中國人"
}
結果:
{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中國人",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "中國",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "國人",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 4
    }
  ]
}

Standard分詞器:

POST _analyze
{
  "analyzer": "standard",
  "text": "我是中國人"
}

結果:
{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "中",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    },
    {
      "token" : "國",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "<IDEOGRAPHIC>",
      "position" : 3
    },
    {
      "token" : "人",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "<IDEOGRAPHIC>",
      "position" : 4
    }
  ]
}

4.2 索引操作

4.2.1 創建索引

語法: PUT /

PUT /my_index

結果:
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "my_index"
}

4.2.2 查看所有索引

語法: GET /_cat/indices?v

image

4.2.3 查看單個索引

語法: GET /

GET /my_index
結果:
{
  "my_index" : {
    "aliases" : { },
    "mappings" : { },
    "settings" : {
      "index" : {
        "creation_date" : "1633499968211",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "bclHUdHrS4W80qxnj3NP0A",
        "version" : {
          "created" : "7080099"
        },
        "provided_name" : "my_index"
      }
    }
  }
}

4.2.4 洗掉索引

語法: DELETE /

DELETE /my_index
結果:
{
  "acknowledged" : true
}

4.3 檔案操作

4.3.1 創建檔案

語法:

PUT /{索引名稱}/{型別}/

{

jsonbody

}

PUT /my_index/_doc/1
{
  "title": "小米手機",
  "category": "小米",
  "images": "http://www.gulixueyuan.com/xm.jpg",
  "price": 3999
}

回傳結果:
{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

4.3.2 查看檔案

語法:GET /{索引名稱}/{型別}/

GET /my_index/_doc/1
結果:
{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "title" : "小米手機",
    "category" : "小米",
    "images" : "http://www.gulixueyuan.com/xm.jpg",
    "price" : 3999
  }
}

4.3.3 修改檔案

語法:

PUT /{索引名稱}/{型別}/

{

jsonbody

}

PUT /my_index/_doc/1
{
  "title": "小米手機",
  "category": "小米",
  "images": "http://www.gulixueyuan.com/xm.jpg",
  "price": 4500
}

4.3.4 修改區域屬性

語法:

POST /{索引名稱}/_update/{docId}
{
"doc": {
"屬性": "值"
}
}

注意:這種更新只能使用post方式,

POST /my_index/_update/1
{
  "doc": {
    "price": 4500
  }
}

4.3.5 洗掉檔案

語法: DELETE /{索引名稱}/{型別}/

DELETE /my_index/_doc/1
結果:
{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 12,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 11,
  "_primary_term" : 1
}

4.3.6 批量操作

{"actionName":{"_index":"indexName", "_type":"typeName","_id":"id"}}

actionName可以有CREATE、DELETE等,

批量創建
POST _bulk
{"create":{"_index":"my_index","_id":2}}
{"id":2,"title":"華為手機","category":"華為","images":"http://www.gulixueyuan.com/xm.jpg","price":5500}
{"create":{"_index":"my_index","_id":3}}
{"id":3,"title":"VIVO手機","category":"vivo","images":"http://www.gulixueyuan.com/xm.jpg","price":3600}

結果:
{
  "took" : 2,
  "errors" : false,
  "items" : [
    {
      "create" : {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_version" : 5,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 20,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "create" : {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_version" : 5,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 21,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}

批量洗掉
POST _bulk
{"delete":{"_index":"my_index","_id":2}}
{"delete":{"_index":"my_index","_id":3}}

結果:
{
  "took" : 3,
  "errors" : false,
  "items" : [
    {
      "delete" : {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_version" : 6,
        "result" : "deleted",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 22,
        "_primary_term" : 1,
        "status" : 200
      }
    },
    {
      "delete" : {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_version" : 6,
        "result" : "deleted",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 23,
        "_primary_term" : 1,
        "status" : 200
      }
    }
  ]
}

4.4 映射mapping

有了索引庫,等于有了資料庫中的database,

接下來就需要建索引庫(index)中的映射了,類似于資料庫(database)中的表結構(table),創建資料庫表需要設定欄位名稱,型別,長度,約束等;索引庫也一樣,需要知道這個型別下有哪些欄位,每個欄位有哪些約束資訊,這就叫做映射(mapping),

4.4.1 查看映射

語法: GET /{索引名稱}/_mapping

GET /my_index/_mapping
結果:
{
  "my_index" : {
    "mappings" : {
      "properties" : {
        "category" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "id" : {
          "type" : "long"
        },
        "images" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "price" : {
          "type" : "long"
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

4.4.2 動態映射

在關系資料庫中,需要事先創建資料庫,然后在該資料庫下創建資料表,并創建 表欄位、型別、長度、主鍵等,最后才能基于表插入資料,而Elasticsearch中不 需要定義Mapping映射(即關系型資料庫的表、欄位等),在檔案寫入 Elasticsearch時,會根據檔案欄位自動識別型別,這種機制稱之為動態映射

映射規則對應:

資料 對應的型別
null 欄位不添加
true|flase boolean
字串 text
數值 long
小數 float
日期 date

4.4.3 靜態映射

靜態映射是在Elasticsearch中也可以事先定義好映射,包含檔案的各欄位型別、分詞器等,這種方式稱之為靜態映射

#洗掉原創建的索引
DELETE /my_index

#創建索引,并同時指定映射關系和分詞器等,
PUT /my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "index": true,
        "store": true,
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_max_word"
      },
      "category": {
        "type": "keyword",
        "index": true,
        "store": true
      },
      "images": {
        "type": "keyword",
        "index": true,
        "store": true
      },
      "price": {
        "type": "integer",
        "index": true,
        "store": true
      }
    }
  }
}

結果:
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "my_index"
}

type分類如下:

  • 字串:string,string型別包含 text 和 keyword,

  • text:該型別被用來索引長文本,在創建索引前會將這些文本進行分詞,轉化為詞的組合,建立索引;允許es來檢索這些詞,text型別不能用來排序和聚合,

  • keyword:該型別不能分詞,可以被用來檢索過濾、排序和聚合,keyword型別不可用text進行分詞模糊檢索,

  • 數值型:long、integer、short、byte、double、float

  • 日期型:date

  • 布爾型:boolean

5. DSL高級查詢

5.1 DSL概述

Query DSL概述: Domain Specific Language(領域專用語言),Elasticsearch提供了基于JSON的DSL來定義查詢,

DSL概覽:

image

準備資料:

POST _bulk
{"create":{"_index":"my_index","_id":1}}
{"id":1,"title":"華為筆記本電腦","category":"華為","images":"http://www.gulixueyuan.com/xm.jpg","price":5388}
{"create":{"_index":"my_index","_id":2}}
{"id":2,"title":"華為手機","category":"華為","images":"http://www.gulixueyuan.com/xm.jpg","price":5500}
{"create":{"_index":"my_index","_id":3}}
{"id":3,"title":"VIVO手機","category":"vivo","images":"http://www.gulixueyuan.com/xm.jpg","price":3600}

5.2 DSL查詢

5.2.1 查詢所有檔案

match_all:

POST /my_index/_search
{
  "query": {
    "match_all": {}
  }
}

結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "id" : 3,
          "title" : "VIVO手機",
          "category" : "vivo",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 3600
        }
      }
    ]
  }
}

5.2.2 匹配查詢(match)

match:

POST /my_index/_search
{
  "query": {
    "match": {
      "title": "華為智能手機"
    }
  }
}

結果:
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.5619608,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.5619608,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.35411233,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      }
    ]
  }
}

補充條件洗掉
POST /my_index/_delete_by_query
{
  "query": {
    "match": {
      "title": "vivo"
    }
  }
}
結果:
{
  "took" : 51,
  "timed_out" : false,
  "total" : 1,
  "deleted" : 1,
  "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" : [ ]
}

5.2.3 多欄位匹配

POST /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "華為智能手機",
      "fields": ["title","category"]
    }
  }
}

結果:
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.5619608,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.5619608,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.35411233,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      }
    ]
  }
}

5.2.4 前綴匹配

POST /my_index/_search
{
  "query": {
   "prefix": {
     "title": {
       "value": "vivo智能"
     }
   }
  }
}
結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

5.2.5 關鍵字精確查詢

term:關鍵字不會進行分詞,

POST /my_index/_search
{
  "query": {
   "term": {
     "title": {
       "value": "華為手機"
     }
   }
  }
}

結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

5.2.6 多關鍵字精確查詢

POST /my_index/_search
{
  "query": {
   "terms": {
     "title": [
       "華為手機",
       "華為"
     ]
   }
  }
}

結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      }
    ]
  }
}

5.2.7 范圍查詢

范圍查詢使用range

  • gte: 大于等于
  • lte: 小于等于
  • gt: 大于
  • lt: 小于
POST /my_index/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 3000,
        "lte": 5000
      }
    }
  }
}
結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "title" : "VIVO手機",
          "category" : "vivo"
        }
      }
    ]
  }
}

5.2.8 指定回傳欄位

query同級增加_source進行過濾,

POST /my_index/_search
{
  "query": {
   "terms": {
     "title": [
       "華為手機",
       "華為"
     ]
   }
  },
  "_source": ["title","category"]
}

5.2.9 組合查詢

bool 各條件之間有and,or或not的關系

  • must: 各個條件都必須滿足,所有條件是and的關系
  • should: 各個條件有一個滿足即可,即各條件是or的關系
  • must_not: 不滿足所有條件,即各條件是not的關系
  • filter: 與must效果等同,但是它不計算得分,效率更高點,
must
POST /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "華為"
          }
        },
        {
          "range": {
            "price": {
              "gte": 3000,
              "lte": 5000
            }
          }
        }
      ]
    }
  }
}
結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
should
POST /my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "華為"
          }
        },
        {
          "range": {
            "price": {
              "gte": 3000,
              "lte": 5000
            }
          }
        }
      ]
    }
  }
}

結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "id" : 3,
          "title" : "VIVO手機",
          "category" : "vivo",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 3600
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.5619608,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.35411233,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      }
    ]
  }
}

如果should和must同時存在,他們之間是and關系:

POST /my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "華為"
          }
        },
        {
          "range": {
            "price": {
              "gte": 3000,
              "lte": 5000
            }
          }
        }
      ],
      "must": [
        {
          "match": {
            "title": "華為"
          }
        },
        {
          "range": {
            "price": {
              "gte": 3000,
              "lte": 5000
            }
          }
        }
      ]
    }
  }
}

結果:
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

must_not
POST /my_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "title": "華為"
          }
        },
        {
          "range": {
            "price": {
              "gte": 3000,
              "lte": 5000
            }
          }
        }
      ]
    }
  }
}
結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
filter

_score的分值為0

POST /my_index/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {
            "title": "華為"
          }
        }
      ]
    }
  }
}

結果:
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.0,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.0,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      }
    ]
  }
}

5.2.10 聚合查詢

聚合允許使用者對es檔案進行統計分析,類似與關系型資料庫中的group by,當然還有很多其他的聚合,例如取最大值、平均值等等,

max
POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0, 
  "aggs": {
    "max_price": {
      "max": {
        "field": "price"
      }
    }
  }
}

結果:
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "max_price" : {
      "value" : 5500.0
    }
  }
}

min
POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0, 
  "aggs": {
    "min_price": {
      "min": {
        "field": "price"
      }
    }
  }
}

結果:
{
  "took" : 12,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "min_price" : {
      "value" : 3600.0
    }
  }
}
avg
POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0, 
  "aggs": {
    "avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}
結果:
{
  "took" : 12,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "avg_price" : {
      "value" : 4829.333333333333
    }
  }
}
sum
POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0, 
  "aggs": {
    "sum_price": {
      "sum": {
        "field": "price"
      }
    }
  }
}
結果:
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "sum_price" : {
      "value" : 14488.0
    }
  }
}
stats
POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0, 
  "aggs": {
    "stats_price": {
      "stats": {
        "field": "price"
      }
    }
  }
}
結果:
{
  "took" : 20,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "stats_price" : {
      "count" : 3,
      "min" : 3600.0,
      "max" : 5500.0,
      "avg" : 4829.333333333333,
      "sum" : 14488.0
    }
  }
}
terms

桶聚和相當于sql中的group by陳述句

POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0, 
  "aggs": {
    "groupby_category": {
      "terms": {
        "field": "category",
        "size": 10
      }
    }
  }
}
結果:
{
  "took" : 16,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "groupby_category" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "華為",
          "doc_count" : 2
        },
        {
          "key" : "vivo",
          "doc_count" : 1
        }
      ]
    }
  }
}

還可以對桶繼續下鉆:

POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0, 
  "aggs": {
    "groupby_category": {
      "terms": {
        "field": "category",
        "size": 10
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}
結果:
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "groupby_category" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "華為",
          "doc_count" : 2,
          "avg_price" : {
            "value" : 5444.0
          }
        },
        {
          "key" : "vivo",
          "doc_count" : 1,
          "avg_price" : {
            "value" : 3600.0
          }
        }
      ]
    }
  }
}

6 進階查詢

6.1 排序

POST /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "華為"
          }
        }
      ]
    }
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    },
    {
      "_score": {
        "order": "desc"
      }
    }
  ]
}
結果:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.35411233,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        },
        "sort" : [
          5388,
          0.35411233
        ]
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.5619608,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        },
        "sort" : [
          5500,
          0.5619608
        ]
      }
    ]
  }
}

6.2 分頁查詢

from、size分頁

分頁的兩個關鍵屬性:from、size,

  • from: 當前頁的起始索引,默認從0開始, from = (pageNum - 1) * size
  • size: 每頁顯示多少條
POST /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 2
}
結果:
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      }
    ]
  }
}
scoll分頁

第一次使用分頁查詢:

POST /my_index/_search?scroll=1m
{
  "query": {
    "match_all": {}
  },
  "size": 1
}
結果:
{
  "_scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFGRKV2JWWHdCeUZ2WWVjeDY1V3NlAAAAAAAAGskWTERWbzhrWFZTdFd3WnVoOV9EaGV0dw==",
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        }
      }
    ]
  }
}

接著就滾動查詢,用第一次回傳的_scroll_id接著查:

GET /_search/scroll?scroll=1m
{
  "scroll_id":"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFHNKV2VWWHdCeUZ2WWVjeDZYbXNGAAAAAAAAGwUWTERWbzhrWFZTdFd3WnVoOV9EaGV0dw=="
}
結果:
{
  "_scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFHNKV2VWWHdCeUZ2WWVjeDZYbXNGAAAAAAAAGwUWTERWbzhrWFZTdFd3WnVoOV9EaGV0dw==",
  "took" : 4,
  "timed_out" : false,
  "terminated_early" : true,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        }
      }
    ]
  }
}

6.3 高亮查詢

在進行關鍵字搜索時,搜索出的內容中的關鍵字會顯示不同的顏色,稱之為高亮,

POST /my_index/_search
{
  "query": {
    "match": {
      "title": "華為"
    }
  },
  "highlight": {
    "pre_tags": "<b style='color:red'>",
    "post_tags": "</b>",
    "fields": {
      "title": {}
    }
  }
}
結果:
{
  "took" : 80,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.8025915,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.8025915,
        "_source" : {
          "id" : 2,
          "title" : "華為手機",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5500
        },
        "highlight" : {
          "title" : [
            "<b style='color:red'>華為</b>手機"
          ]
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.49191093,
        "_source" : {
          "id" : 1,
          "title" : "華為筆記本電腦",
          "category" : "華為",
          "images" : "http://www.gulixueyuan.com/xm.jpg",
          "price" : 5388
        },
        "highlight" : {
          "title" : [
            "<b style='color:red'>華為</b>筆記本電腦"
          ]
        }
      }
    ]
  }
}

6.4 近似查詢

回傳包含與搜索字詞相似的字詞的檔案,編輯距離是將一個術語轉換為另一個術語所需的一個字符更改的次數,這些更改可以包括:

  • 更改字符(box → fox)
  • 洗掉字符(black → lack)
  • 插入字符(sic → sick)
  • 轉置兩個相鄰字符(act → cat)

為了找到相似的術語,fuzzy查詢會在指定的編輯距離內創建一組搜索詞的所有可能的變體或擴展,然后查詢回傳每個擴展的完全匹配,通過fuzziness修改編輯距離,一般使用默認值AUTO,根據術語的長度生成編輯距離,

PUT /test

PUT /test/_doc/1
{
  "title":"hello world"
}

#fuzzy查詢
GET /test/_search
{
  "query": {
    "fuzzy": {
      "title": {
        "value": "word"
      }
    }
  }
}

結果:
{
  "took" : 633,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.21576157,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.21576157,
        "_source" : {
          "title" : "hello world"
        }
      }
    ]
  }
}

7. java api 操作 es

官方參考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-getting-started.html

7.1 構建client

RestHighLevelClient client = new RestHighLevelClient(RestClient
                .builder(new HttpHost("192.168.85.157", 9200, "http")));

7.2 索引操作

	//創建索引
    @Test
    public void createIndex(){
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(INDEX);
        try {
            createIndexRequest.mapping("{\n" +
                    "    \"properties\": {\n" +
                    "      \"name\": {\n" +
                    "        \"type\": \"keyword\",\n" +
                    "        \"index\": true,\n" +
                    "        \"store\": true\n" +
                    "      },\n" +
                    "      \"age\": {\n" +
                    "        \"type\": \"integer\",\n" +
                    "        \"index\": true,\n" +
                    "        \"store\": true\n" +
                    "      },\n" +
                    "      \"remark\": {\n" +
                    "        \"type\": \"text\",\n" +
                    "        \"index\": true,\n" +
                    "        \"store\": true,\n" +
                    "        \"analyzer\": \"ik_max_word\",\n" +
                    "        \"search_analyzer\": \"ik_max_word\"\n" +
                    "      }\n" +
                    "    }\n" +
                    "  }", XContentType.JSON);
            CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            System.out.println(createIndexResponse.isAcknowledged());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //查看索引
    @Test
    public void getIndex(){
        GetIndexRequest request = new GetIndexRequest(INDEX);
        try {
            GetIndexResponse getIndexResponse = client.indices().get(request, RequestOptions.DEFAULT);
            System.out.println(getIndexResponse.getMappings());
            System.out.println(getIndexResponse.getSettings());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //洗掉索引
    @Test
    public void deleteIndex(){
        DeleteIndexRequest request = new DeleteIndexRequest(INDEX);
        try {
            AcknowledgedResponse acknowledgedResponse = client.indices().delete(request, RequestOptions.DEFAULT);
            System.out.println(acknowledgedResponse.isAcknowledged());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

7.3 檔案操作

	//創建檔案
    @Test
    public void createDocument(){
        IndexRequest request = new IndexRequest(INDEX);
        request.id("1");
        Student student = new Student();
        student.setAge(18);
        student.setName("robin");
        student.setRemark("good man");
        request.source(JSONObject.toJSONString(student), XContentType.JSON);
        try {
            IndexResponse index = client.index(request, RequestOptions.DEFAULT);
            System.out.println(index.getResult());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //修改檔案
    @Test
    public void updateDocuemnt(){
        UpdateRequest request = new UpdateRequest(INDEX,"1");
        try {
            Student student = new Student();
            student.setRemark("very good man");
            request.doc(JSONObject.toJSONString(student), XContentType.JSON);
            UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
            System.out.println(response.getResult());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //根據ID查詢
    @Test
    public void getDocument(){
        GetRequest request = new GetRequest(INDEX,"1");
        try {
            GetResponse response = client.get(request, RequestOptions.DEFAULT);
            System.out.println(response.getSourceAsString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //批量操作
    @Test
    public void bulkDocument(){
        BulkRequest request = new BulkRequest();
        Student student = new Student();
        for(int i=0;i<10;i++){
            student.setAge(18 + i);
            student.setName("robin" + i);
            student.setRemark("good man " + i);
            request.add(new IndexRequest(INDEX).id(String.valueOf(10 + i)).source(JSONObject.toJSONString(student), XContentType.JSON));
        }
        try {
            BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
            for(BulkItemResponse itemResponse : response.getItems()){
                System.out.println(itemResponse.isFailed());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //洗掉檔案
    @Test
    public void deleteDocument(){
        DeleteRequest request = new DeleteRequest(INDEX,"11");
        try {
            DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
            System.out.println(response.getResult());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

7.4 DSL查詢

	private static final String MY_INDEX = "my_index";

    /**
     * dsl查詢檔案:
     * {
     *   "query": {
     *     "match": {
     *       "title": "華為智能手機"
     *     }
     *   }
     * }
     * */
    @Test
    public void search(){
        SearchRequest request = new SearchRequest(MY_INDEX);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("title","華為智能手機"));
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            for(SearchHit hit : response.getHits().getHits()){
                System.out.println(hit.getSourceAsString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 高亮查詢
     * */
    @Test
    public void highlightSearch(){
        SearchRequest request = new SearchRequest(MY_INDEX);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("title","華為智能手機"));
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<b style='color:red'>");
        highlightBuilder.postTags("</b>");
        builder.highlighter(highlightBuilder);
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            for(SearchHit hit : response.getHits().getHits()){
                System.out.println(hit.getSourceAsMap().get("title") + ":" +hit.getHighlightFields().get("title").fragments()[0].string());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 聚合查詢
     * */
    @Test
    public void aggsSearch(){
        SearchRequest request = new SearchRequest(MY_INDEX);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        AggregationBuilder aggregationBuilder = AggregationBuilders
                .terms("groupby_category").field("category");
        aggregationBuilder.subAggregation(AggregationBuilders.avg("avg_price").field("price"));
        builder.aggregation(aggregationBuilder);
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            Aggregations aggregations = response.getAggregations();
            Terms terms = aggregations.get("groupby_category");
            terms.getBuckets().forEach(bucket -> {
                Avg avg = bucket.getAggregations().get("avg_price");
                System.out.println(bucket.getKeyAsString() + ":" + bucket.getDocCount() + "," + avg.getValue());
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/544189.html

標籤:其他

上一篇:3、TreeMap原始碼決議

下一篇:Flink CDC 監聽 Postgresql表的變化

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more