概念
Elasticsearch 是一個開源的搜索引擎,建立在一個全文搜索引擎庫 Apache Lucene™ 基礎之上。
然而,Elasticsearch 不僅僅是 Lucene,並且也不僅僅只是一個全文搜索引擎。 它可以被下面這樣准確的形容:
- 一個分布式的實時文檔存儲,每個字段 可以被索引與搜索
- 一個分布式實時分析搜索引擎
- 能勝任上百個服務節點的擴展,並支持 PB 級別的結構化或者非結構化數據
來自 https://www.elastic.co/guide/cn/elasticsearch/guide/current/intro.html
index、type、document (索引、類型、文檔)
Index 里面單條的記錄稱為 Document(文檔)。許多條 Document 構成了一個 Index。
文檔使用json格式表示:
curl -X PUT 'localhost:9200/megacorp/employee/1' -d '
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}'
說明:
megacorp:索引名稱
employee:類型名稱
1:特定雇員的ID
安裝
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.zip
unzip elasticsearch-5.5.1.zip
cd elasticsearch-5.5.1/
./bin/elasticsearch
注意:不能使用root運行es;並且elasticsearch-5.5.1 這個目錄所有者不是root。
curl localhost:9200
索引操作
新增索引
curl -X PUT 'localhost:9200/user'
服務端返回json:
{"acknowledged":true,"shards_acknowledged":true}
查詢索引
curl -X GET 'localhost:9200/user?pretty=true'
# pretty=true 表示結果以易讀的形式展示出來
服務端返回json:
{
"user" : {
"aliases" : { },
"mappings" : { },
"settings" : {
"index" : {
"creation_date" : "1516421830842",
"number_of_shards" : "5",
"number_of_replicas" : "1",
"uuid" : "tY2XLVTmTGCkCe4Y9cw_0w",
"version" : {
"created" : "5050199"
},
"provided_name" : "user"
}
}
}
}
返回當前節點的所有Index
curl -X GET 'http://localhost:9200/_cat/indices?v'
### 刪除索引
``` shell curl -X DELETE 'localhost:9200/user'
服務端返回json:
{"acknowledged":true}
----------
## 文檔操作</br>
### 新增文檔
``` shell
curl -X PUT 'localhost:9200/user/admin_user/1' -d '
{
"userName": "張三",
"title": "工程師",
"desc": "數據庫管理"
} '
在user索引在新建類型為admin_user的文檔,1是這個文檔的id。第一個admin_user有三個屬性:user、title、desc。
新增文檔也可以不指定ID,這里的ID不一定要數字。不指定ID時要用POST請求。
新增文檔不指定ID:
curl -X POST 'localhost:9200/user/admin_user/?pretty=true' -d '
{
"userName" : "李四",
"title" : "工程師",
"desc" : "網絡管理"
} '
返回:_id 就是隨機的字符串。
{
"_index" : "user",
"_type" : "admin_user",
"_id" : "AWESLcupvcrWFMesxEQY",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
更新文檔也是用put,刪除用DELETE。
查詢文檔
curl -X GET 'localhost:9200/user/admin_user/1?pretty=true'
結果:
{
"_index" : "user",
"_type" : "admin_user",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"userName" : "張三",
"title" : "工程師",
"desc" : "數據庫管理"
}
}
"found":true 表示查詢成功。
查詢所有結果:
curl -X GET localhost:9200/user/admin_user/_search?pretty=true
結果:
{
"took" : 75,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "user",
"_type" : "admin_user",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"userName" : "張三",
"title" : "工程師",
"desc" : "數據庫管理"
}
},
{
"_index" : "user",
"_type" : "admin_user",
"_id" : "AWESLcupvcrWFMesxEQY",
"_score" : 1.0,
"_source" : {
"userName" : "李四",
"title" : "工程師",
"desc" : "網絡管理"
}
}
]
}
}
一個搜索默認返回10條結果。
### match查詢
以上的查詢是帶ID查詢,返回所有文檔,還有一種就是自定義查詢,自己封裝查詢參數,實現全文搜索。Match查詢主要是模糊匹配,不僅能返回結果,而且對結果還有相似度的判定。
Match參數設置
查詢用戶名為張三的文檔:
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=true' -d'
{
"query":{"match":{"userName":"張三"}}
} '
結果:
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.7600523,
"hits" : [
{
"_index" : "user",
"_type" : "admin_user",
"_id" : "1",
"_score" : 1.7600523,
"_source" : {
"userName" : "張三",
"title" : "工程師",
"desc" : "數據庫管理"
}
}
]
}
}
上面提到,一次查詢默認返回10條記錄,這里可以設置查詢結果的條數。
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=true' -d'
{
"query":{"match":{"userName":"三"}},
"size": 12
} '
用了這種match方式去匹配查詢,結果中有個_score這個屬性,也就是相似度的參數(相關性得分)。
這里match不能匹配多個字段。匹配多個字段要使用multi_match
[match] query doesn't support multiple fields, found [userName]and[title]
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=true' -d'
{
"query":{
"multi_match":{
"query":"張三",
"fields": ["userName","title"]
}
}
} '
去匹配userName字段和title字段,匹配關鍵字就是 張三。
### bool查詢
Bool查詢相當於sql中的 OR AND NOT。
同一個字段用空格隔開表示 OR 。查詢只會匹配當前字段,且多個關鍵詞都會匹配。
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=true' -d'
{
"query":{"match":{"userName":"三 四"}}
} '
這里的查詢會去匹配userName中有 三 和 四的記錄。
bool查詢也可以查詢多個字段
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=true' -d'
{
"query": {
"bool": {
"must": [
{ "match": { "userName": "三" } },
{ "match": { "title": "師" } }
]
}
}
}'
結果:
Bool查詢中的關鍵字有:
- must
所有的語句都 必須(must) 匹配,與 AND 等價。 - must_not
所有的語句都 不能(must not) 匹配,與 NOT 等價。 - should
至少有一個語句要匹配,與 OR 等價。
bool查詢也可以多個條件嵌套使用:
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=true' -d'
{
"query": {
"bool": {
"must":[
{ "match": { "desc": "管理" } }
],
"should":[
{"match" : {"title":"師"}} ,
{"match": { "userName": "三" }}
]
}
}
}'
這樣匹配的結果中desc字段中一定有 '管理',要么title中有' 師 ',要么userName中有' 三 '。
Range查詢
在本實例中user索引的類型是admin_user,字段都為字符類型,需要再加一個數字類型的字段,相同的索引下可以有不同類型的數據結構,也就是type可以不唯一。可以直接插入新的文檔:
curl -X POST 'localhost:9200/user/admin_user/?pretty=true' -d '
{
"userName" : "李四",
"title" : "工程師",
"desc" : "網絡管理",
"age" : 27
} '
range 查詢找出那些落在指定區間內的數字或者時間:
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=ture' -d '
{
"query":{
"range":{
"age" : { "gte":20, "lt":30 }
}
}
}'
查詢age在20到30之間的記錄。
Range操作符如下:
- gt:大於
- gte:大於等於
- lt:小於
- lte:小於等於
term查詢
term 查詢被用於精確值匹配。在match查詢中,會對輸入值進行分詞,然后再去匹配。term查詢則沒有分詞這個過程,輸入值是什么就去匹配什么。
curl -X GET 'localhost:9200/user/admin_user/_search?pretty=true' -d'
{
"query":{"term":{"desc":"網絡,管理"}},
"size": 12
} '
結果什么都匹配不到:
更多搜索方式:https://www.elastic.co/guide/cn/elasticsearch/guide/current/_more_complicated_searches.html
注意,如果沒有先創建 Index(這個例子是user),直接執行上面的命令,ES 也不會報錯,而是直接生成指定的 Index。所以,不要寫錯 Index 的名稱。
安裝ES遇到的一些問題
failed ; error = ' Cannot allocate memory (errno=12)'
vim jvm.options
# change to 512m
-Xms512m
-Xms512m
can not run elasticsearch as root
root 用戶不能執行,需要創建其他用戶運行。
groupadd elsearch
useradd elsearch -g elsearch
passwd elsearch
main ERROR Could not register mbeans java.security.AccessControlException:access denied
切換到普通用戶出現的問題
需要把elasticSearch目錄的所有者改變成當前用戶:(-R 遞歸該目錄下的所有文件)
sudo chown -R elsearch:elsearch elasticSearch
ERROR:[1] bootstrap check failed
修改 config/elasticsearch.yml之后無法啟動
切換到root用戶,
vi /etc/security/limits.conf
添加如下內容:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
此文件修改后需要重新登錄用戶,才會生效