全文搜索是什么
全文搜索引擎就是通過從互聯網上提取的各個網站的信息(以網頁文字為主)而建立的數據庫中,檢索與用戶查詢條件匹配的相關記錄,然后按一定的排列順序將結果返回給用戶。
ES是一個基於 Lucene 庫的搜索引擎。它提供了一個分布式的、支持多租戶的全文搜索引擎,該引擎具有 HTTP web 界面和無模式的 JSON 文檔。是用 Java 開發的。遵循開放核心業務模式,部分軟件根據各種開放源碼許可證(主要是 Apache 許可證)進行許可,而其他部分則根據專有(源碼可用)彈性許可證進行許可。官方客戶端可以在 Java,。NET (c #)、 PHP、 Python、 Apache Groovy、 Ruby 和許多其他語言。據 DB-Engines 排名,Elasticsearch 是最受歡迎的企業搜索引擎,其次是 Apache Solr,也是基於 Lucene 的.

安裝
服務端,以macOS為例brew install elasticsearch

安裝好了直接運行 curl localhost:9200

上面代碼中,請求9200端口,Elastic 返回一個 JSON 對象,包含當前節點、集群、版本等信息。
默認情況下,Elastic 只允許本機訪問,如果需要遠程訪問,可以修改 Elastic 安裝目錄的
config/elasticsearch.yml文件,去掉network.host的注釋,將它的值改成0.0.0.0,然后重新啟動 Elastic。
客戶端,以python為例
python -m pip install elasticsearch

基本概念
Elastic 本質上是一個分布式數據庫,允許多台服務器協同工作,每台服務器可以運行多個 Elastic 實例。
單個 Elastic 實例稱為一個節點(node)。一組節點構成一個集群(cluster)。
Elastic 會索引所有字段,經過處理后寫入一個反向索引(Inverted Index)。查找數據的時候,直接查找該索引。
所以,Elastic 數據管理的頂層單位就叫做 Index(``索引)。它是單個數據庫的同義詞。每個 Index (即數據庫)的名字必須是小寫。
Index 里面單條的記錄稱為 Document(文檔)。許多條 Document 構成了一個 Index。
Document 可以分組,比如weather這個 Index 里面,可以按城市分組(北京和上海),也可以按氣候分組(晴天和雨天)。這種分組就叫做 Type,它是虛擬的邏輯分組,用來過濾 Document。
http://localhost:9200/_mapping?pretty=true 這個命令可以列出每個 Index 所包含的 Type。

基本操作 新建和刪除
新建 Index,可以直接向 Elastic 服務器發出 PUT 請求。下面的例子是新建一個名叫weather的 Index。
服務器返回一個 JSON 對象,里面的acknowledged字段表示操作成功。
$ url -X PUT 'localhost:9200/weather'
{"acknowledged":true,"shards_acknowledged":true,"index":"weather"}%
然后,我們發出 DELETE 請求,刪除這個 Index。
curl -X DELETE 'localhost:9200/weather'
{"acknowledged":true}%
中文分詞 (選)
要安裝和elasticsearch版本匹配的。安裝命令elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/xxxx.zip

新建一個 account 的index curl -X PUT 'localhost:9200/accounts' -H 'Content-Type: application/json' -d ', person是Type。
curl -X PUT 'localhost:9200/accounts' -H 'Content-Type: application/json' -d '
{
"mappings": {
"person": {
"properties": {
"user": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}'
{"error":{"root_cause":[{"type":"resource_already_exists_exception","reason":"index [accounts/_tFhzXBbTvakegDC4k64TQ] already exists","index_uuid":"_tFhzXBbTvakegDC4k64TQ","index":"accounts"}],"type":"resource_already_exists_exception","reason":"index [accounts/_tFhzXBbTvakegDC4k64TQ] already exists","index_uuid":"_tFhzXBbTvakegDC4k64TQ","index":"accounts"},"status":400}%
數據操作
在account里面,新增一條記錄
curl -X PUT -H 'Content-Type: application/json' 'localhost:9200/accounts/person/1' -d '
{
"user": "張三",
"title": "工程師",
"desc": "數據庫管理"
}'
{"_index":"accounts","_type":"person","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":1,"_primary_term":2}
如果你仔細看,會發現請求路徑是
/accounts/person/1,最后的1是該條記錄的 Id。它不一定是數字,任意字符串(比如abc)都可以。
新增記錄的時候,也可以不指定 Id,這時要改成 POST 請求。
curl -X POST -H 'Content-Type: application/json' 'localhost:9200/accounts/person/' -d '
{
"user": "張三",
"title": "工程師",
"desc": "數據庫管理"
}'
{"_index":"accounts","_type":"person","_id":"5vzIE3YBFWECnAW261hs","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":2,"_primary_term":2}
注意,如果沒有先創建 Index(這個例子是accounts),直接執行上面的命令,Elastic 也不會報錯,而是直接生成指定的 Index。所以,打字的時候要小心,
不要寫錯 Index 的名稱。
新增了后,查詢記錄curl 'localhost:9200/accounts/person/1?pretty=true'
curl 'localhost:9200/accounts/person/1?pretty=true'
{
"_index" : "accounts",
"_type" : "person",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 2,
"found" : true,
"_source" : {
"user" : "張三",
"title" : "工程師",
"desc" : "數據庫管理"
}
}
返回的數據中,found字段表示查詢成功,_source字段返回原始記錄。
如果 Id 不正確,就查不到數據,found字段就是false。
curl 'localhost:9200/accounts/person/32?pretty=true'
{
"_index" : "accounts",
"_type" : "person",
"_id" : "32",
"found" : false
}
更新記錄就是使用 PUT 請求,重新發送一次數據。
curl -X PUT 'localhost:9200/accounts/person/1' -H 'Content-Type: application/json' -d '
{
"user" : "張三",
"title" : "工程師",
"desc" : "數據庫管理,軟件開發"
}'
{"_index":"accounts","_type":"person","_id":"1","_version":3,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":3,"_primary_term":2}
可以看到,上面更新記錄的 Id 沒變,但是版本(version)從2變成3,操作類型(result)從created變成updated,created字段變成false,因為這次不是新建記錄。
查詢更新成功沒, 更新成功。

查詢所有的記錄。
curl 'localhost:9200/accounts/person/_search'
{"took":57,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"accounts","_type":"person","_id":"1","_score":1.0,"_source":
{
"user" : "張三",
"title" : "工程師",
"desc" : "數據庫管理,軟件開發"
}},{"_index":"accounts","_type":"person","_id":"5vzIE3YBFWECnAW261hs","_score":1.0,"_source":
{
"user": "張三",
"title": "工程師",
"desc": "數據庫管理"
}}]}}
上面字段的含義
- total:返回記錄數,本例是2條。
- max_score:最高的匹配程度,本例是1.0。
- hits:返回的記錄組成的數組。
返回的記錄中,每條記錄都有一個_score字段,表示匹配的程序,默認是按照這個字段降序排列。
帶有參數查詢 query, 默認是10條記錄,可以設置size和from。
官方說明文檔: https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-match-query.html
curl 'localhost:9200/accounts/person/_search' -H 'Content-Type: application/json' -d '
{
"query" : { "match" : { "desc" : "軟件" }}
}'
{"took":28,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.241217,"hits":[{"_index":"accounts","_type":"person","_id":"1","_score":1.241217,"_source":
{
"user" : "張三",
"title" : "工程師",
"desc" : "數據庫管理,軟件開發"
}}]}}
有支持邏輯運算,如果有多個搜索關鍵字, Elastic 認為它們是or關系。
下面代碼搜索的是軟件 or 系統。
curl 'localhost:9200/accounts/person/_search' -d '
{
"query" : { "match" : { "desc" : "軟件 系統" }}
}'
還有 and 的查詢, 下面就是and的操作
curl 'localhost:9200/accounts/person/_search' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "desc": "軟件" } },
{ "match": { "desc": "系統" } }
]
}
}
}'
刪除記錄
curl -X DELETE 'localhost:9200/accounts/person/1'
{"_index":"accounts","_type":"person","_id":"1","_version":4,"result":"deleted","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":4,"_primary_term":2}
readmore
https://www.elastic.co/blog/a-practical-introduction-to-elasticsearch
https://www.ruanyifeng.com/blog/2017/08/elasticsearch.html
https://en.wikipedia.org/wiki/Elasticsearch
https://elasticsearch-py.readthedocs.io/en/7.10.0/
github博客
微信公眾號:chasays, 歡迎關注一起吹牛逼,也可以加微信號「xxd_0225」互吹。
