elasticsearch 學習筆記
1 基本概念
1.1 接近實時(NRT)
Elasticsearch 是一個接近實時的搜索平臺,從索引一個文檔到這個文檔被搜索到有一個很小的延遲(通常是1s)
1.2 集羣(Cluster)
一個集羣就是由一個節點組織在一起,他們共同持有你全部的數據,並且一起提供索引與搜索功能。一個集羣由一個唯一的名字標識,一個節點通常指定某個集羣的名字來加入這個集羣。
一個集羣中只包含一個節點是合法的。另外你可以擁有多個集羣,以名字劃分
1.3 節點(Node)
一個節點直觀點說就是一個集羣中的一臺服務器,作爲集羣的一部分,它存儲你的數據,參與集羣的索引和搜索功能。它也是用一個名字來標識的。默認情況下,這個名字是隨機的Marvel角色的名字,這個名字會在節點啓動的時候被分配。
一個節點可以通過配置集羣名稱的方式加入一個指定的集羣,默認情況下,每個節點都會被加入名叫”elasticsearch”的集羣當中。
1.4 索引(Index)
一個索引就是一個擁有相似特徵的文檔集合。比如說學生數據索引,訂單數據索引。一個索引由一個名字來標識(必須全是小寫字母),並且當我們對這個索引中的文檔進行搜索,更新,刪除的時候都會用到這個名字。在一個集羣中,你能夠創建任意多的索引。
1.5 類型(Type)
在一個索引中,你可以指定多個類型。一個類型是索引的一個邏輯上的分類,通常會以一組相同字段的文檔定義一個類型。比如我們要設計一個博客系統,那麼這個博客系統就是一個索引,博客系統中的用戶數據定義一個類型,博客數據可以定義一個類型。
1.6 文檔(Document)
一個文檔是一個可以被索引的基礎信息單元,比如我們可以擁有一個客戶文檔,產品文檔,訂單文檔,文檔以json的形式存儲。在一個index/type中可以有多個文檔,但是注意,一個文檔物理上存在於一個索引中,但是文檔必須被索引/賦予一個索引的type
1.7 分片和複製 (Shards and Replicas)
一個索引可以存儲超出單個節點硬件限制的大量數據。比如一個具有10億文檔的索引佔據1TB的磁盤空間,但是任何一個節點都不能提供這麼大的存儲空間,爲了解決這個問題,Elasticsearch提供了將索引劃分成多個分片的能力。當創建索引的時候,可以指定創建多少分片數量。每個分片本身也是一個具有功能完善並且獨立的“索引”。
分片之所以重要,主要原因有:
- 允許水平分割/擴展容量
- 允許在分片之上進行分佈式,並行操作,提高性能/吞吐量
在網絡環境裏,某個分片完全有可能處於離線活着消失的狀態,故障轉移機制是非常重要的,因此Elasticsearch 允許我們創建分片的一份活着多份拷貝,這叫複製。
複製重要的原因:
- 高可用
- 搜索可以在所有的複製上並行操作,複製可以擴展搜索量
默認情況下,Es(Elasticsearch的簡稱)爲我們每個索引創建5個主分片和一個複製,這就意味着集羣中至少有兩個節點,索引會將有5個主分片和另外5個複製分片,也就是一個索引一共有10個分片。
ps 這裏索引,類型,文檔,分片複製的概念可能有點模糊的同學,我可以舉一個相似的��
ES —- > Mysql
Index —- > database
Type —- > table
Document —- > table.rows
Shards —- > sharding
Replicas —- > master and slave僅僅是做概念上的理解幫助,兩者並不是一種東西
2. 安裝
Elasticsearch 需要 java7以及以上版本
用下面的命令下載 Elasticsearch 1.4.2 tar 包
curl -L -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.2.tar.gz
將其解壓並且啓動單個節點的集羣
tar -xvf elasticsearch-1.4.2.tar.gz
cd elasticsearch-1.4.2/bin
./elasticsearch
我們可以覆蓋集羣或者節點的名字啓動
./elasticsearch --cluster.name my_cluster_name --node.name my_node_name
默認情況下,Elasticsearch使用9200來提供REST API 的訪問,如果有必要,這個端口是可以被配置的
其二進制文件也可以從 官網
3 操作集羣
3.1 rest 接口
現在我們已經有一個正常運行的節點(和集羣),下一步就是要去理解如果與其通信。幸運的是,ES提供了非常全面強大的REST API, 利用這個REST API 可以與集羣交互,下面我們搞點事情。
3.2 集羣健康
我們使用Curl或者任何一個可以創建HTTP/REST調用的工具來使用該功能
命令
GET localhost:9200/_cat/health?v
響應
epoch timestamp cluster status node.total node.data shards pri relo init unassign
1489252285 02:11:25 elasticsearch green 1 1 0 0 0 0 0
下面默認此格式(上一個是請求,下一個是響應) ⚠️
我們查到集羣名字是”elasticsearch”,狀態green
- green 一切正常(集羣功能齊全)
- yello 所有數據是可用的,但是某些複製沒有分配(功能齊全)
- red 由於某些原因,數據不可用
上面的響應中,可以看出 一個集羣,一個節點,沒有分片,由於我們默認配置,所以es使用多播
的發現其他節點。
3.3 列出所有節點
GET localhost:9200/_cat/nodes?v
host ip heap.percent ram.percent load node.role master name
localhost 127.0.0.1 10 90 0.15 d * Vulture
3.4 列出所有索引
GET localhost:9200/_cat/indices?v
health index pri rep docs.count docs.deleted store.size pri.store.size
沒有索引
3.5 創建索引
PUT localhost:9200/test?pretty
{
"acknowledged" : true
}
pretty 美麗的用json打印返回
GET localhost:9200/_cat/indices?v
health status index pri rep docs.count docs.deleted store.size pri.store.size
yellow open test 5 1 0 0 575b 575b
yellow 代表沒有複製,因爲默認情況下,ES會分配一個複製,但是現在只有一個節點,所以複製用不了
3.5 索引一個文檔
因爲如果索引一個文檔,必須有個類型(Type),我們把一個學生信息索引入test
PUT localhost:9200/test/student/1
curl -i -X PUT \
-H "Content-Type:application/json" \
-d \
'{
"name":"igouc"
}' \
'http://localhost:9200/test/student/1'
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 1,
"created": true
}
1 代表id爲 1
索引這個文檔
GET localhost:9200/test/student/1?pretty
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 1,
"found": true,
"_source":{
"name": "igouc"
}
}
除了found字段-(指明我們找到了一個ID爲1的文檔)和_source字段(返回我們前一步中索引的完整JSON文檔)之外,沒有什麼特別之處。
3.6 刪除一個文檔
- 刪除索引
curl -XDELETE 'localhost:9200/test?pretty'
{
"acknowledged" : true
}
- 刪除類型
curl -XDELETE 'localhost:9200/test/student?pretty'
{
"acknowledged" : true
}
- 刪除文檔
curl -XDELETE 'localhost:9200/test/student/1?pretty'
{
"name": "igouc"
}
3.7 訪問格式
仔細研究以上的命令,我們可以發現訪問Elasticsearch中數據的一個模式。這個模式可以被總結爲:
<REST Verb> <Node>:<Port>/<Index>/<Type>/<ID>
4 修改數據
Elasticsearch提供了近乎實時的數據操作和搜索功能。默認情況下,從你索引/更新/刪除你的數據動作開始到它出現在你的搜索結果中,大概會有1秒鐘的延遲。這和其它的SQL平臺不同,它們的數據在一個事務完成之後就會立即可用。
4.1 索引/替換文檔
curl -i -X PUT \
-H "Content-Type:application/json" \
-d \
'{
"name":"igouc4"
}' \
'http://localhost:9200/test/student/1?pretty'
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 2,
"created": false
}
注意created == false
GET localhost:9200/test/student/1
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 2,
"found": true,
"_source":{
"name": "igouc4"
}
}
如果不指定最後的id,則會自動分配id,注意要用POST⚠️
curl -i -X POST \
-H "Content-Type:application/json" \
-d \
'{
"name":"igouc5"
}' \
'http://localhost:9200/test/student/?pretty'
{
"_index": "test",
"_type": "student",
"_id": "AVq-d-gpHptku1SmEgQL",
"_version": 1,
"created": true
}
此時的id是隨機的
4.2 更新文檔
curl -i -X POST \
-H "Content-Type:application/json" \
-d \
'{
"doc":{"name":"igouc6"}
}' \
'http://localhost:9200/test/student/1/_update?pretty'
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 4
}
GET localhost:9200/test/student/1?pretty
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 4,
"found": true,
"_source":{
"name": "igouc6"
}
}
更新文檔,Elasticsearch先刪除舊文檔,然後再索引更新的新文檔。且用POST
更新也可以通過使用簡單的腳本來進行
curl -i -X POST \
-H "Content-Type:application/json" \
-d \
'{
"script":"ctx._source.name += 2"
}' \
'http://localhost:9200/test/student/1/_update?pretty'
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 5
}
GET localhost:9200/test/student/1?pretty
{
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 5,
"found": true,
"_source":{
"name": "igouc62"
}
}
4.3 刪除數據
刪除文檔是非常直觀的
DELETE localhost:9200/test/student/1?pretty
{
"found": true,
"_index": "test",
"_type": "student",
"_id": "1",
"_version": 6
}
指定刪除條件
curl -i -X DELETE \
-H "Content-Type:application/json" \
-d \
'{
"query": { "match": { "name": "igouc2" } }
}' \
'http://localhost:9200/test/student/_query?pretty'
{
"_indices":{
"test":{
"_shards":{
"total": 5,
"successful": 5,
"failed": 0
}
}
}
}
4.4 批處理
下面兩個僅僅是指令,沒有響應
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
'
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}
'
bulk API按順序執行這些動作。如果其中一個動作因爲某些原因失敗了,它將會繼續處理後面的動作。當bulk API返回時,它將提供每個動作的狀態(按照同樣的順序),所以你能夠看到某個動作成功與否。⚠️
5 操作數據
我們有兩種基本的搜索方式:
- REST請求 URI中發送請求參數
- REST請求 將請求參數放在請求體中
下面 我們僅僅使用一次 將請求參數放入URI中,其餘都將參數放入請求體,以便美觀
GET localhost:9200/bank/_search?q=*$pretty
{
"took" : 9,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1000,
"max_score" : 1.0,
"hits" : [ {
"_index" : "bank",
"_type" : "account",
"_id" : "4",
"_score" : 1.0,
"_source":{"account_number":4,"balance":27658,"firstname":"Rodriquez","lastname":"Flores","age":31,"gender":"F","address":"986 Wyckoff Avenue","employer":"Tourmania","email":"[email protected]","city":"Eastvale","state":"HI"}
}, {
"_index" : "bank",
"_type" : "account",
"_id" : "9",
"_score" : 1.0,
"_source":{"account_number":9,"balance":24776,"firstname":"Opal","lastname":"Meadows","age":39,"gender":"M","address":"963 Neptune Avenue","employer":"Cedward","email":"[email protected]","city":"Olney","state":"OH"}
}, {
"_index" : "bank",
"_type" : "account",
"_id" : "11",
"_score" : 1.0,
"_source":{"account_number":11,"balance":20203,"firstname":"Jenkins","lastname":"Haney","age":20,"gender":"M","address":"740 Ferry Place","employer":"Qimonk","email":"[email protected]","city":"Steinhatchee","state":"GA"}
}, {
"_index" : "bank",
"_type" : "account",
"_id" : "16",
"_score" : 1.0,
"_source":{"account_number":16,"balance":35883,"firstname":"Adrian","lastname":"Pitts","age":34,"gender":"F","address":"963 Fay Court","employer":"Combogene","email":"[email protected]","city":"Remington","state":"SD"}
},
.
.
.
.
}
我們看看這個請求的響應體
- took 這個查詢所消耗的時間(ms)
- timed_out 是否超時
- _shards 指出了多少分片被搜索了,同時也指出了成功/失敗的分片數量
- hits 搜索結果
- hits.total 匹配查詢條件的文檔的總數目
- hits.hits 真正的搜索結果數組(默認是前10個文檔)
- _score 匹配度,得分越高,相關性越大 *
如果我們是使用請求體的話,應該這樣:
POST localhost:9200/bank/_search?pretty
body:
{
"query":{"match_all":{}}
}
我們來分析下這個請求體
- query 高速我們定義請求體
- match_all 高速我們想要運行的查詢類型
當然除了上面的參數,還可以指定返回的條數(默認10條)
POST localhost:9200/bank/_search?pretty
body:
{
"query":{"match_all":{}},
"from":10,
"size":1
}
上面的這條表示從第10條查詢1條
POST localhost:9200/bank/_search?pretty
body:
{
"query":{"match_all":{}},
"sort":{"account_number":{"order":"desc"}}
}
現在我們已經接觸了一些簡單的搜索語句,下面我們執行一些特殊的搜索
默認情況下,都是返回所有的字段,我們下面可以 用_source
指定返回的字段
POST localhost:9200/bank/_search?pretty
body
{
"query":{"match_all":{}},
"_source":["account_number", "balance", "firstname"]
}
現在讓我們進入到查詢部分。之前,我們學習了match_all查詢是怎樣匹配到所有的文檔的。現在我們介紹一種新的查詢,叫做match查詢,這可以看成是一個簡單的字段搜索查詢(比如對某個或某些特定字段的搜索)
下面這個例子返回賬戶編號爲 20 的文檔:
POST localhost:9200/bank/_search?pretty
body:
{
"query":{"match":{"account_number":999}}
}
下面這個例子返回地址中包含詞語(term)“mill”的所有賬戶:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill" } }
}'
下面這個例子返回地址中包含詞語“mill” 或者“lane” 的賬戶:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill lane" } }
}'
下面這個例子是match的變體(match_phrase),它會去匹配短語“mill lane”:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_phrase": { "address": "mill lane" } }
}'
現在,讓我們介紹一下布爾查詢。布爾查詢允許我們利用布爾邏輯將較小的查詢組合成較大的查詢。
現在這個例子組合了兩個match查詢,這個組合查詢返回包含“mill” 和“lane” 的所有的賬戶
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
在上面的例子中,bool must語句指明瞭,對於一個文檔,所有的查詢都必須爲真,這個文檔才能夠匹配成功。
相反的, 下面的例子組合了兩個match查詢,它返回的是地址中包含“mill” 或者“lane”的所有的賬戶:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"should": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
在上面的例子中bool should語句指明,對於一個文檔,查詢列表中,只要有一個查詢匹配,那麼這個文檔就被看成是匹配的。
現在這個例子組合了兩個查詢,它返回地址中既不包含“mill”,同時也不包含“lane”的所有的賬戶信息:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must_not": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
在上面的例子中,bool must_not語句指明,對於一個文檔,查詢列表中的的所有查詢都必須都不爲真,這個文檔才被認爲是匹配的。
我們可以在一個bool查詢裏一起使用must、should、must_not。 此外,我們可以將bool查詢放到這樣的bool語句中來模擬複雜的、多層級的布爾邏輯。
下面這個例子返回40歲以上並且不生活在ID(aho)的人的賬戶:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "age": "40" } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}'
Elasticsearch中的所有的查詢都會觸發相關度得分的計算。對於那些我們不需要相關度得分的場景下,Elasticsearch以過濾器的形式提供了另一種查詢功能。過濾器在概念上類似於查詢,但是它們有非常快的執行速度,這種快的執行速度主要有以下兩個原因:
- 過濾器不會計算相關度的得分,所以它們在計算上更快一些
- 過濾器可以被緩存到內存中,這使得在重複的搜索查詢上,其要比相應的查詢快出許多。
爲了理解過濾器,我們先來介紹“被過濾” 的查詢,這使得你可以將一個查詢(如match_all,match,bool等)和一個過濾器結合起來。作爲一個例子,我們介紹一下範圍過濾器,它允許我們通過一個區間的值來過濾文檔。這通常被用在數字和日期的過濾上。
這個例子使用一個被過濾的查詢,其返回值是存款在20000到30000之間(閉區間)的所有賬戶。換句話說,我們想要找到存款大於等於20000並且小於等於30000的賬戶。
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"filtered": {
"query": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}'
分析上面的例子,被過濾的查詢包含一個match_all查詢(查詢部分)和一個過濾器(filter部分)。我們可以在查詢部分中放入其他查詢,在filter部分放入其它過濾器。 在上面的應用場景中,由於所有的在這個範圍之內的文檔都是平等的(或者說相關度都是一樣的), 沒有一個文檔比另一個文檔更相關,所以這個時候使用範圍過濾器就非常合適了
通常情況下,要決定是使用過濾器還是使用查詢,你就需要問自己是否需要相關度得分。如果相關度是不重要的,使用過濾器,否則使用查詢。如果你有SQL背景,查詢和過濾器 在概念上類似於SELECT WHERE語句,一般情況下過濾器比查詢用得更多。
除了match_all, match, bool,filtered和range查詢,還有很多其它類型的查詢/過濾器,我們這裏不會涉及。由於我們已經對它們的工作原理有了基本的理解,將其應用到其它類型的查詢、過濾器上也不是件難事。
我們可以在es上做聚合操作:
聚合提供了分組並統計數據的能力。理解聚合的最簡單的方式是將其粗略地等同爲SQL的GROUP BY和SQL聚合函數。在Elasticsearch中,你可以在一個響應中同時返回命中的數據和聚合結果。你可以使用簡單的API同時運行查詢和多個聚合並一次返回,這避免了來回的網絡通信,是非常強大和高效的。
作爲開始的一個例子,我們按照state分組,並按照州名的計數倒序排序:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state"
}
}
}
}'
注意我們將size設置成 0,這樣我們就可以只看到聚合結果了,而不會顯示命中的結果。
在先前聚合的基礎上,現在這個例子計算了每個州的賬戶的平均存款(還是按照賬戶數量倒序排序的前10個州):
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}'
注意, 我們把average_balance聚合嵌套在了group_by_state聚合之中。這是所有聚合的一個常用模式。你可以在任意的聚合之中嵌套聚合,這樣就可以從你的數據中抽取出想要的結果。
在前面的聚合的基礎上,現在讓我們按照平均餘額進行排序:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state",
"order": {
"average_balance": "desc"
}
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}'
6 搜索API
搜索API允許開發者執行搜索查詢,返回匹配的搜索結果。這樣既可以通過查詢字符串,也可以通過查詢實體實現。
6.1 多索引類型
所有的搜索API都可以跨多個類型使用,也可以通過多索引語法跨索引使用,例如,我們可以搜索twitter索引的跨類型的所有的文檔。
GET http://localhost:9200/twittper/_search?q=user:ki
我們也可以帶上特定搜索的type:
GET htto://localhost:9200/twittper/type1,type2/_search?q=user:ki
我們也可以誇index搜索
GET http://localhost:9200/type1,type2/twitter/_search?q=user:ki
我們可以用_all
來充當所有的佔位符
GET http://localhost:9200/_all/twitter/_search?q=user:ki
或者省略_all
GET http://localhost:9200/twitter/_search?q=user:ki
6.2 URL搜索
一個搜索可以用uri來執行,用這種方法進行搜索,並不是所有的選項都是暴露出來的,下面我們記錄這些參數
Name | Description |
---|---|
q | 表示查詢 |
df | 在查詢中,當沒有定義字段的前綴的情況下的默認字段前綴 |
analyzer | 當分析查詢字符串時,分析器的名字 |
explain | 對於命中,會得到一個命中解釋 |
_source | 將其設置爲false,查詢就會放棄檢索_source字段。你也可以通過設置_source_include和_source_exclude檢索部分文檔 |
fields | 命中的文檔返回的字段 |
sort | 排序執行。可以以fieldName、fieldName:asc或者fieldName:desc的格式設置。fieldName既可以是存在的字段,也可以是_score字段。可以有多個sort參數 |
track_scores | 當排序的時候,將其設置爲true,可以返回相關度得分 |
timeout | 默認沒有timeout |
from | 默認0 |
size | 默認10 |
search_type | 搜索操作執行的類型,有dfs_query_then_fetch, dfs_query_and_fetch, query_then_fetch, query_and_fetch, count, scan幾種,默認是query_then_fetch |
lowercase_expanded_terms | terms是否自動小寫,默認是true |
analyze_wildcard | 是否分配通配符和前綴查詢,默認是false |
6.3 請求體搜索
有搜索DSL的搜索請求可以被執行
6.3.1 查詢
精準匹配
{
"query":{
"term":{
"shop_name":"測試"
}
}
}
模糊匹配(表達式匹配)
{
"query":{
"match":{
"shop_name":"測試"
}
}
}
6.3.2 from/size
{
"query":{
"term":{
"shop_name":"test"
}
},
"from":0,
"size":100
}
6.3.3 排序
{
"query":{
"term":{
"shop_name":"test"
}
},
"sort":[{"age":"asc"},{"_score":"desc"}]
}
6.3.4 排序值
es支持通過數組數組或者多值字段排序
mode選項控制 用多值字段的什麼值來排序
- min 最小值
- max 最大值
- sum 和 (僅用數值)
- avg 平均值(僅用數值)
{
"query":{
"term":{
"shop_name":"test"
}
},
"sort":[
{"price":{"order":"desc", "mode":"avg"}}
]
}
6.3.5 缺失字段的處理方式
missing
參數指缺失字段的處理方式:”missing”:”_last”/”missing”:”true”
{
"sort" : [
{ "price" : {"missing" : "_last"} },
],
"query" : {
"term" : { "user" : "kimchy" }
}
}
6.3.6 地理位置排序
通過_geo_distance排序。
{
"sort" : [
{
"_geo_distance" : {
"pin.location" : [-70, 40],
"order" : "asc",
"unit" : "km",
"mode" : "min",
"distance_type" : "sloppy_arc"
}
}
],
"query" : {
"term" : { "user" : "kimchy" }
}
}
- distance_type:怎樣計算距離可以有sloppy_arc(默認),arc(更精確但是顯著變慢),plane(最快)
地理距離排序支持的排序mode有max,min和avg。
6.4 source過濾
用於控制_source字段的返回。默認情況下,操作返回_source字段的內容,除非你用到了fields參數,或者_source被禁用了。你能夠通過_source參數關掉_source檢索。
{
"_source": false,
"query" : {
"term" : { "user" : "kimchy" }
}
}
_source也接受一個或者多個通配符模式控制返回值。
{
"_source":"obj.*",
"query" : {
"term" : { "user" : "kimchy" }
}
}
or
{
"_source": [ "obj1.*", "obj2.*" ],
"query" : {
"term" : { "user" : "kimchy" }
}
}
_source裏面也可以有include/exclude
{
"query":{
"term":{"shop_name":"test"}
},
"_source":{
"include":["object.*", "a.*"],
"exclude":["object1.*"]
}
}
6.5 字段
es允許選擇性地加載文檔特定的存儲字段。
{
"fields" : ["user", "postDate"],
"query" : {
"term" : { "user" : "kimchy" }
}
}
如果fields數組爲空,那麼就只會返回_id和_type字段。
6.6 分數
{
"min_score": 0.5,
"query" : {
"term" : { "user" : "kimchy" }
}
}
返回的文檔的得分小於min_score。
7 java API
ES可以在多個地方用到 java client
- 在集羣中執行標準的index, delete, get, search
- 在集羣中執行管理任務
- 當你要運行嵌套在你的應用程序中的Elasticsearch的時候或者當你要運行單元測試或者集合測試的時候,啓動所有節點
獲得一個Client是非常容易的,最通用的步驟如下所示:
- 創建一個嵌套的節點,充當集羣的一個節點
- 從這個嵌套的節點請求一個Client
另外一種方式是創建一個TransportClient來連接集羣。
重要提示: 客戶端和集羣端推薦使用相同的版本,如果版本不同,可能會出現一些不兼容的問題。