Elasticsearch-ais是我新寫的Elasticsearch框架(或者也可以稱之爲springboot組件),他的操作方式非常簡單,比現有的Elasticsearch操作方式都簡單,希望大家可以使用
導入
<dependency>
<groupId>com.github.lihang212010</groupId>
<artifactId>ais</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
<optional>true</optional>
</dependency>
ELASTICSEARCH-AIS
ELASTICSEARCH-AIS
地址:https://github.com/lihang212010/Elasticsearch-ais
javadoc:http://49.232.76.209:8080/download/apidocs/
爲什麼使用ais
更簡單接近原生的代碼操作
estemplate.term(“worker”,“farmer”); //這是查詢worker屬性爲farmer的結果
自動映射結果
@RequestMapping("terms")
public List<User> terms() throws IOException {
estemplate.terms("age",25,35,10,68);
return estemplate.execute(index,User.class);
}
可以直接複製kibana中的代碼
@RequestMapping("/findCustom")
public List<User> findCustom(User user) throws IllegalAccessException, NoSuchFieldException, IOException {
String script="GET demo/_search\n" +
"{\n" +
" \"query\": {\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" {\n" +
" \"wildcard\": {\n" +
" \"name\": {\n" +
" \"value\": \"#{name}\"\n" +
" }\n" +
" }\n" +
" },\n" +
" {\n" +
" \"term\": {\n" +
" \"id\": {\n" +
" \"value\": \"#{id}\"\n" +
" }\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"must_not\": [\n" +
" {\n" +
" \"range\": {\n" +
" \"age\": {\n" +
" \"gte\": #{age}\n" +
" }\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n" +
" \"from\": \"#{pageFrom}\",\n" +
" \"size\": \"#{pageSize}\"\n" +
"}";
return estemplateCustom.excute(script,user);
}
對複雜需求的處理可以使用json和java代碼
@Elasticsearch
public interface UserJson {
List findName(String name);
List findIdName(String name,String id);
}
{
“findName”: {
“requestMethod”: “GET”,
“index”: “demo/_search”,
“script”: {
“query”: {
“wildcard”: {
“name”: {
“value”: “#{name}”
}
}
}
}
},
“findIdName”: {
"requestMethod": "GET",
"index": "demo/_search",
"script": {
"query": {
"bool": {
"must": [
{
"wildcard": {
"name": {
"value": "#{name}"
}
}
},
{
"term": {
"id": {
"value": "#{id}"
}
}
}
]
}
}
}
}
}
@[TOC](maven導入)
簡單配置
pop.xml
<dependency>
<groupId>com.github.lihang212010</groupId>
<artifactId>ais</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
<optional>true</optional>
</dependency>
@[TOC](配置文件配置屬性)
elasticsearch.ais.url=node-3:9200 集羣則用逗號隔開
elasticsearch.ais.aisResource=com.ais @Elasticsearch註解的接口位置,不配置則掃描所有路徑,會導致springboot啓動較慢,建議配置爲項目路徑
elasticsearch.ais.userName="" 用戶名
elasticsearch.ais.passWard="" 密碼
elasticsearch.ais.socketTimeout=30000 socket連接超時時間
elasticsearch.ais.connectTimeout=10000 connect連接超時時間
elasticsearch.ais.scheme="http" 訪問方式
elasticsearch.ais.header="" 請求頭
elasticsearch.ais.value="" 請求頭對應值
elasticsearch.ais.jsonPath=static json文件路徑
@[TOC](ESTEPLATE,簡單例子)
ESTEPLATE,最簡單的操作
Esteplate是ais中最簡單也是最常用的操作Elasticsearch的操作方式,它可以讓你只用幾行代碼就輕鬆實現所需要的功能。
在使用的時候我們只需要藉助spring中的注入,便可以輕鬆使用
@Autowired
Estemplate estemplate;
下面我簡單的寫出幾個使用例子,這些例子只是展示ais操作的簡單。
@Autowired
Estemplate estemplate;
@RequestMapping("/insert1")
public void insert1(List<User> list,String index) throws IOException {
estemplate.insert(list,index);
}
User是一個實體類實際上我們的操作只有 estemplate.insert(list,index); 這麼一行,index是對應插入的索引位置,list則是一個實體類List,ais會自動排除List中的空值,所以並不需要我們對空值進行判斷。
當然除了這些ais還支持Map對象的插入和單一實體類的插入。
@Autowired
Estemplate estemplate;
@RequestMapping("/delete")
public void delete(String index,String id) throws IOException {
estemplate.delete(index,id);
}
index是需要刪除的對應索引,id則是需要刪除的id
查詢是Elasticsearch中最重要最常用的功能
而ais簡化了足夠平常工作需求的查詢操作,對於過於複雜的操作,Elasticsearch也提供了類似Mybatis的方式進行操作。
@Autowired
Estemplate estemplate;
public List<User> find() throws IOException {
estemplate.wildcard("name","li");
estemplate.term("worker","farmer");
estemplate.rangelte("age",18);
return estemplate.execute("/demo/user",User.class);
}
比如我們需要查詢name屬性中包含li,worker屬性等於farmer,age小於等於18的對象,只需要3行查詢和一行執行即可。
@[TOC](插入)
插入
ais支持3種方式的插入,批量插入和單一一條數據的插入,它插入的對應api只有一行
estemplate.insert(list,index);
list爲需要插入的數據,它支持3種方式,List,Map,和單一實體類,index爲對應索引(elasticsearch7中拋棄了type)
對於我們需要插入一條數據的情況,User爲對應實體類
@Autowired
Estemplate estemplate;
public void insert3(String index,User user) throws IOException {
estemplate.insert(user,index);
}
對於需要插入一組數據的情況
public void insert1(List<User> list,String index) throws IOException {
estemplate.insert(list,index);
}
對於需要插入一組數據並且自定義每一個數據的對應id時
public void insert2(Map<Object,User> map,String index) throws IOException {
estemplate.insert(map,index);
}
map中的鍵爲你需要設置的id,值則是對應的數據
@[TOC](查詢)
查詢
查詢是Elasticsearch中最重要的操作,Esteplate封裝的查詢與Elasticsearch中的查詢操作是非常相似的,如果你熟練使用kibana,則可以無難度使用ais的查詢,當然,你如果沒有操作過kibana,也可以很快上手ais的查詢。
查詢規則
Esteplate默認所有查詢爲query查詢,但是同樣支持過濾查詢,這裏簡單說一下Elasticsearch的2種查詢,過濾查詢(filter)和評分查詢(query),評分查詢會對查詢結果進行打分排序,但性能方面略次於過濾查詢,因此我們可以對不要求查詢結果的選項進行過濾查詢
Esteplate的將查詢分爲4類
must 必須滿足的查詢
must_not 必須不滿足的查詢
filter_must 必須滿足的過濾查詢
filter_must_not 必須不滿足的過濾查詢
Esteplate的默認查詢爲must查詢,但是可以在第一個參數中修改本次查詢的查詢方式
如:
estemplate.term("worker","farmer"); //這是查詢worker屬性爲farmer的結果
estemplate.term("must_not","worker","farmer"); //這是查詢worker屬性不爲farmer的結果
estemplate.term("filter_must","worker","farmer"); //這是通過過濾查詢查詢worker屬性爲farmer的結果
estemplate.term("filter_must_not","worker","farmer"); //這是通過過濾查詢查詢worker屬性不爲farmer的結果
Esteplate會默跳過空值
比如
estemplate.wildcard("name","li");
estemplate.term("worker","");
estemplate.rangelte("age",18);
worker如果爲空值,則本次查詢將只對name和age進行查詢
@[TOC](查詢相關API)
這些API如果你操縱過kibana,一定會非常屬性,他和Elasticsearch中的名字是相同的,如果你不太明白,本文將提供一些簡單的使用場景,對於每一個查詢的具體內容,更建議Elasticsearch官方文檔
.
.
.
查詢常用參數
type, 查詢的方式,默認爲must,可以選擇must_not,filter_must ,filter_must_not
key, 對應字段,查詢的對應屬性在Elasticsearch中名稱
value, 需要查詢的對應值
index 對應索引
boost 排名分數比例,默認爲1
具體API
查詢相關的API
term 準確查詢,必備參數:key,value 可選參數type,boost
wildcard 左右模糊查詢,必備參數:key,value 可選參數:type,boost
match 分詞查詢,必備參數key,value 可選參數type,boost
wildcardLeft 左模糊查詢,必備參數:key,value 可選參數:type,boost
wildcardRight 右模糊查詢,必備參數:key,value 可選參數:type,boost
wildcardFree 自定義模糊查詢,必備參數:key,value 可選參數:boost
terms 包含查詢,必備參數key,value,這裏的value可以是數組和一個數,可選參數:type
match_phrase 短語匹配,必備參數key,value,可選參數:slop:作用爲詞與詞之間允許相隔的單詞數目; type
match_phrase_prefix 短語前綴匹配,必備參數key,value,可選參數:slop:詞與詞之間允許相隔的單詞數目,max_expansions:指定前綴最多匹配多少結果; type
common 高頻率查詢,通過排除文章中的常用詞來提高查詢結果,不影響性能,必備參數:key,value,cutoff_frequency:排除文章中出現頻率多少的詞,可選參數:type
exits 判斷某一屬性是否存在,必備參數key,可選參數:type
fuzzy 糾錯查詢,會允許輸入的參數有多少錯誤,必備參數:key,value,可選參數:fuzziness:允許多少錯誤,prefix_length:精確查詢的長度,type
geo_shape 地理位置查詢,必備參數:key,coordinates:地理位置座標,通常爲一個多維數組,relation:查詢方式
ids id查詢,必備參數values,可以是一個id,也可以是一個id組成的數組,可選參數:type
multi_match 多字段分詞查詢,必備參數value,需要查找的值,keys,對應的字段數組,可選參數:type
more_like_this 必須包含詞查詢,要求某(一個或多個)字段內容必須包含某一分詞,必備參數:value:必須包含的分詞,keys:字段,可以是一個或多個,min_term_freq:最小包含數目,
max_query_terms:最多包含數目,可選參數:type
percolate 索引屬性查詢,對某一字段的索引屬性進行查詢,必備字段:key,value,field:存索引查詢 的類型的字段,可選參數,type
prefix 左模糊(較爲推薦),必備字段,key,value,可選參數:boost,type
query_string 較爲嚴格的字符串查詢(可以進行和或非等操作,但如果查詢中包含無效內容,則查詢失敗),必備字段:default_field:對應字段,query_:查詢內容,可選參數:type
range 範圍查詢,必備參數:key,gte:大於等於的數值,lte小於等於的數值,可選參數:type
rangegte 大於等於範圍查詢,必備參數:key,gte:大於等於的數值,可選參數:type
rangelte 小於等於範圍查詢,必備參數:key,lte小於等於的數值,可選參數:type
regexp 正則查詢,必備參數:key,value,可選參數:max_determinized_states:查詢所需最大數目,默認10000,flags:可選運算符,type
script 腳本,可以自由植入自己想進行的語句,必備參數:source:植入的腳本,可選參數,lang,params,type
simple_query_string 使用較爲簡單的符號操作進行查詢(如+-|等),查詢更爲嚴格,必備參數:value,filed:一個或多個字段,可選參數:type
wripper 接受其他查詢內容的查詢,必備參數:query:其餘查詢的base64編碼,可選參數:type
findFree 插入Elasticsearch原生的語句,默認參數:query:插入的語句,可選參數:type
should 可以進行或之類的操作,也可以進行加分,minimum_should_match:最少滿足多少項
.
.
.
處理結果相關的API(這些操作較爲簡單,不依依展示,將會在幾個常用查詢例子中展示)
source 字段篩選,可以讓結果之顯示幾個字段,參數:fields:一個或多個字段
version 是否顯示版本號
timeout 查詢時間
stored_fields 另一種不太被推薦的字段篩選
stats 結果統計
sort 排序,如果需要對多個值進行排序,請在奇數位寫需要排序的字段,偶數位寫排序規則
size (分頁)每一頁的最大數目
from (分頁)從第幾頁開始查詢
script_fields 腳本
profile 是否查看具體的聚合搜索過程以及具體耗時情況
partial_fields 更加強大更爲推薦的字段篩選
indices_boost 相關度控制
highlight 高亮,可選字段pre_tags:高亮字段前面添加內容,post_tags:後面添加內容
explain 是否開啓查看如何評分
collapse 字段摺疊
docvalue_fields 另一種查詢,節省空間但會禁止使用sort、aggregate、access the field from script等
查詢結果:(以下3種查詢均勻異步查詢方法,使用方法類似)
excute 獲得所有查詢結果並映射到實體類,參數:index:索引名,tClass:需要的返回值類型,requestMethod:請求方式
excuteOne 執行所有查詢,參數:index:索引名,tClass:需要的返回值類型,requestMethod:請求方式,tClass:需要的返回值類型
excuteJson 執行所有查詢並返回最原始的就是哦你結果,參數:index:索引名,requestMethod:請求方式
如果你對這些查詢有所疑問,接下來將會用幾個簡單的例子展示這些查詢
@[TOC](wildcard)
wildcard是模糊查詢,假如,我們有這樣一組數據
在ais中我們可以這樣
estemplate.wildcard("name","範");
這樣便會查詢於所有名字中包含“範”的內容
而在kibana中的查詢是這樣的
GET demo/_search
{
“query”: {
“wildcard”: {
“name”: {
“value”: “範”
}
}
}
}
estemplate.wildcardLeft("name","範");
這樣則是查詢name中所有範開頭的內容
estemplate.wildcardRight("name","範");
這樣則是查詢name中所有範結尾的內容
estemplate.wildcardFree("name","*範*");
使用wildcardFree則需要自己插入匹配符號*或者. *是匹配多個字符,.是匹配一個
@[TOC](term)
term是準確搜索
Elasticsearch一些版本中對字段屬性中含有keyword必須加keyword,沒有keyword屬性則無所謂
estemplate.term("name.keyword","奚範");
查詢name中值爲奚範的熟悉
kibana中
GET demo/_search
{
“query”: {
“term”: {
“name.keyword”: {
“value”: “奚範”
}
}
}
}
@[TOC]match
match是分詞查詢,什麼是分詞查詢
比如:我們是朋友
它是由我們,朋友,是3個詞組成的
在elasticsearch使用match查詢這3個詞中的任意一個都應該得到我們是朋友結果。
同樣我們的查詢內容也會被分詞,然後去和文章內容的分詞比較
match查詢是elasticsearch中的核心查詢,對於中文查詢來說比較著名的是IK分詞器
在ais中
estemplate.match("name","奚範");
在kibana中
GET demo/_search
{
“query”: {
“match”: {
“name”: {
“query”: “奚範”
}
}
}
}
@[TOC]terms
terms又叫包含查詢
例如
estemplate.terms("age",25,35,10,68);
它可以查詢age屬性爲23,35,10,68的所有數據,也可以查詢age是一個數組,數組中有這幾個數字中的數據
比如在程序中執行後這是我得到的一些結果
在kibana中的terms
GET demo/_search
{
“query”: {
“terms”: {
“age”: [10,25,35,68]
}
}
}
@[TOC](match_phrase)
match_phrase是短語查詢
estemplate.match_phrase("title","We friends",2);
2是允許詞與詞之間最大相隔幾個單詞
在文中title的內容爲We are good friends,而我們查詢的內容是We friends,中間少一個good,但是我們允許詞與詞之間可以有2個相隔單詞,所以可以查詢到對應內容
kibana中語句
GET demo/_search
{
“query”: {
“match_phrase”: {
“title”: {
“query”: “We friends”,
“slop”: 2
}
}
}
}
@[TOC](match_phrase_prefix)
match_phrase_prefix 比起match_phrase多了個前綴查詢
還是這組數據
estemplate.match_phrase_prefix("title","We good f",2);
這句話的意思是查詢語句中We are good然後下一個單詞的首字母爲f開頭的數據,可以允許最多空2個詞
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“match_phrase_prefix”: {
“title”: {
“query”: “We good f”,
“max_expansions”: 10,
“slop”:2
}
}
}
]
}
}
}
@[TOC](common)
common主要作用是排除查詢選項中一些常用詞比如英語中的is,are,漢語中的是,我,他之類
參數:cutoff_frequency:出現的頻率
使用方式
estemplate.common("title","We are",0.01);
kibana中
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“match_phrase_prefix”: {
“title”: {
“query”: “We good f”,
“max_expansions”: 10,
“slop”:2
}
}
}
]
}
}
}
@[TOC](extis)
extis 判斷某一屬性是否存在
estemplate.exits("title");
kibana中使用方式
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“common”: {
“title”: {
“query”: “We are”,
“cutoff_frequency”: 0.01
}
}
}
]
}
}
}
@[TOC](fuzzy)
fuzzy是一種允許錯誤的term查詢
參數:fuzziness:允許多少錯誤
estemplate.fuzzy("name","李松",1);
因爲允許一個錯誤所以可以查詢李張,和張松這些數據
kibana中的
GET demo/_search
{
“query”: {
“fuzzy”: {
“name”: {
“value”: “孫a”,
“fuzziness”: 1
}
}
}
}
@[TOC](ids)
查詢某一個id,注意Elasticsearch一般是獨立與存儲數據的,所以一般會設置id等於數據中的某一字段
使用方式
estemplate.ids("09EprnABqEAuwq_e8YJH","19EprnABqEAuwq_e8YJH");
查詢這2個id的對應數據
或者
estemplate.ids("09EprnABqEAuwq_e8YJH");
查詢此id對應數據
kibana中
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“ids”: {
“values”: [
“09EprnABqEAuwq_e8YJH”,
“19EprnABqEAuwq_e8YJH”
]
}
}
]
}
}
}
@[TOC](multi_match)
multi_match 多字段分詞查詢
.
estemplate.multi_match("are","name","title");
查詢在name和title字段中含有are單詞的數據
.
kibana中代碼
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“multi_match”: {
“query”: “are”,
“fields”: [
“name”,
“title”
]
}
}
]
}
}
}
@[TOC](more_like_this)
more_like_this 必須包含詞查詢,要求某(一個或多個)字段內容必須包含某一分詞,必備參數:value:必須包含的分詞,keys:字段,可以是一個或多個,min_term_freq:最小包含數目,
max_query_terms:最多包含數目,可選參數:type
.
estemplate.more_like_this(1,10,"are","title");
作用:查詢出字段title中含有1-10個are的數據
.
kibana中代碼
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“more_like_this”: {
“fields”: [
“title”
],
“like”: “are”,
“min_term_freq”: 1,
“max_query_terms”: 10
}
}
]
}
}
}
@[TOC](prefix)
PREFIX
左模糊查詢
estemplate.prefix("name","李");
查詢所有姓“李”的
.
kibana中代碼
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“prefix”: {
“name”: {
“value”: “李”
}
}
}
]
}
}
}
@[TOC](query_string)
query_string 較爲嚴格的字符串查詢(可以進行和或非等操作,但如果查詢中包含無效內容,則查詢失敗),必備字段:default_field:對應字段,query_:查詢內容,可選參數:type
estemplate.query_string("name","(孫李) OR (李周)");
查詢name爲孫李或者李周的人
.
kibana中
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“query_string”: {
“default_field”: “name”,
“query”: “(孫李)OR(李周)”
}
}
]
}
}
}
@[TOC](range)
range 範圍查詢,必備參數:key,gte:大於等於的數值,lte小於等於的數值,可選參數:type
.
estemplate.range("age",10,100);
查詢age在10和100之間的數據
.
estemplate.rangelte("age",100);
查詢age小於100的數據
estemplate.rangegte("age",10);
查詢age大於10的數據
.
kibana中語句
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“range”: {
“age”: {
“gte”: 10,
“lte”: 100
}
}
}
]
}
}
}
@[TOC](regexp)
regexp 正則查詢,必備參數:key,value,可選參數:max_determinized_states:查詢所需最大數目,默認10000,flags:可選運算符,type
.
estemplate.regexp("name","孫.?");
查詢孫開頭的字
當然正則表達式的寫法很多,幾乎可以滿足所有需求,大家可以自行百度
.
kibana中代碼
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“regexp”: {
“name”: {
“value”: “孫.?”
}
}
}
]
}
}
}
@[TOC](script)
script 腳本,可以自由植入自己想進行的語句,必備參數:source:植入的腳本,可選參數,lang,params,type
script是高級elasticsearch程序員的必備技能,它使用了另一種語言,本文將不在具體解釋,只提供一個簡單例子
.
estemplate.script("doc['age']>10");
查詢age大於10的數據
.
kibana中代碼
GET demo/_search
{
“query”: {
“bool”: {
“must”: [
{
“regexp”: {
“name”: {
“value”: “孫.?”
}
}
}
]
}
}
}
@[TOC](findFree)
findFree 插入Elasticsearch原生的語句,默認參數:query:插入的語句,可選參數:type
對於api中沒有的查詢方式或者更爲麻煩的查詢方式或者想自己拼寫代碼的人可以使用
String query="{\n" +
" \"term\": {\n" +
" \"name.keyword\": {\n" +
" \"value\": \"奚範\"\n}" +
" }\n" +
" }";
estemplate.findFree(query);
@[TOC](should)
should是或操作,在ais中使用着稍顯複雜
estemplate.should(1,Find.term("name","張三"),Find.term("name","liu"));
這個是在後面的2個精確情況下必須滿足其中其中一個
Find是一個靜態類,他的使用方式和Esteplate相似
@[TOC](幾個常用的查詢例子)
幾個常用的查詢例子
@RestController
public class Finds {
@Autowired
Estemplate estemplate;
private String index="demo";
/*
* 這個查詢爲age在10和48之間,但不在22-24的,name首字母爲李的,title中含有are,worker是Teacher或者Doctor的從0位開始到第20位
* */
@RequestMapping("find1")
public List<User> find1() throws IOException {
estemplate.range("age",10,48);
estemplate.range("must_not","age",22,24);
estemplate.prefix("name","李");
estemplate.wildcard("title","are");
estemplate.terms("worker","Teacher","Doctor");
estemplate.from(0);
estemplate.size(20);
return estemplate.execute(index,User.class);
}
/*
* 姓名是張三或者liu的age大於20的
* */
@RequestMapping("find2")
public List<User> find2() throws IOException {
estemplate.script("doc['age']>20");
estemplate.should(1,Find.term("name","張三"),Find.term("name","liu"));
estemplate.from(0);
estemplate.size(20);
return estemplate.execute(index,User.class);
}
}
@[TOC](在前後端分離或者微服務中查詢的簡單使用)
在前後端分離或者微服務中的簡單使用
@RestController
public class FindController {
@Autowired
Estemplate estemplate;
private String index="demo";
/*
* User爲實體類,ais中默認會排除空值,所以並不需要檢測空值
* */
@RequestMapping("find")
public List<User> find(User user) throws IOException {
estemplate.prefix("name",user.getName());
estemplate.wildcard("title",user.getTitle());
estemplate.term("age",user.getAge());
estemplate.wildcard("data",user.getDate());
estemplate.from(0);
estemplate.size(20);
return estemplate.execute(index,User.class);
}
}
@[TOC](修改)
修改有3種,一種是修改單一屬性的
Map中的key爲你要修改的字段,value爲要修改的值
public void update(String id, Map<String,Object> map,String index) throws IOException {
estemplate.update(id,map,index);
}
這一種是批量修改,第一個Map的key是id,Map中的Map的key爲你要修改的字段,value爲要修改的值
public void update1(Map<String,Map<String,Object>> map,String index) throws IOException {
estemplate.update(map,index);
}
還有一種是藉助查詢規則的修改
例如下面的是將所有名字中包含李的修改title爲***
@RequestMapping("/update_by_query")
public void update_by_query() throws IOException {
estemplate.wildcard("name","李");
Map<String,String> map=new HashMap();
map.put("title","We are good friends. Our friendship will last forever");
estemplate.update_by_query(map,index);
}
@[TOC](刪除)
刪除ais有2種刪除
一種是根據id刪除,可以根據一個或多個id
public void delete(String index,String id) throws IOException {
estemplate.delete(index,id);
}
public void delete(String index,String ...id) throws IOException {
estemplate.delete(index,id);
}
另一種是藉助查詢規則進行刪除,比如下面的例子是刪除所有age等於10歲的
public void delete_query() throws IOException {
estemplate.term("age","10");
estemplate.delete_by_query("demo");
}
@[TOC](實體類的增刪改差模板使用)
POJOTEMPLATE-一個實體類的增刪改差
POJOTemplate是一個對實體類進行規則定義的模板,在使用它的時候我們只需要繼承POJOTemplate這個抽象類,然後定義相對應的查詢規則
例如:
@Repository
public class UserTemplate extends POJOTemplate {
/*
* 設置索引
* */
@Override
public void setIndex() {
this.index="demo";
}
/*
* 設置分頁等屬性
* */
@Override
public void setConfig(User entity) {
estemplate.from(entity.getPageFrom());
estemplate.size(entity.getPageSize());
}
/*
* 設置可以通過id和name進行查詢
* */
@Override
public void findRule(User user) {
estemplate.term("id",user.getId());
estemplate.wildcard("name.keyword",user.getName());
}
}
首先我們要定義他對應的索引名字,然後定義它的一些設置規則(如分頁高亮等)和查詢規則,然後我們便可以根據對應的id或者name進行查詢,修改,刪除等操作(默認刪除和修改使用的是查詢規則)
@RestController
public class FindController {
@Resource
UserTemplate userTemplate;
@RequestMapping("findUser")
public List<User> findUser(User user) throws IOException {
return userTemplate.find(user);
}
@RequestMapping("updateUser")
public String updateUser(User user) throws IOException {
try {
Map<String,String> map=new HashMap<>();
map.put("name","走姊姊");
return userTemplate.update(user,map).toString();
}catch (Exception e){
return e.toString();
}
}
@RequestMapping("insertUser")
public String insertUser(User user){
try {
return userTemplate.insert(user).toString();
} catch (Exception e) {
return "error" + e;
}
}
@RequestMapping("deleteUser")
public String deleteUser(User user){
try {
return userTemplate.delete(user).toString();
}catch (Exception e){
return e.toString();
}
}
}
@[TOC](模板規則)
模板使用的一些規則
POJO是一種非常容易的對elasticsearch操作的方法,使用它可以我們甚至將實體類中沒一個屬性都去寫一個查詢規則,將查詢,修改,刪除,增加等操作簡化成一個類。
但是使用它的時候要注意一點
默認刪除,查詢和修改使用的規則都是查詢規則,他們能夠共同使用的原因是因爲Esteplate會自動跳過對空值的查詢,因此,如果你需要使用自定義查詢findFree時,請做好空值處理。
另外,如果你不想自己的刪除修改和查詢使用同一規則,那麼你可以給他們沒一個都定義對應的規則
如:
@Repository
public class UserTemplate extends POJOTemplate {
@Override
public void setIndex() {
this.index="demo";
}
@Override
public void setConfig(User entity) {
estemplate.from(entity.getPageFrom());
estemplate.size(entity.getPageSize());
}
/*
* 設置可以通過id和name進行查詢
* */
@Override
public void findRule(User user) {
estemplate.term("id",user.getId());
estemplate.wildcard("name.keyword",user.getName());
}
/*
* 設置的只可以使用id進行刪除
* */
@Override
public void deleteRule(User user){
estemplate.term("id",user.getId());
}
/*
* 設置的只可以使用name進行修改
* */
@Override
public void updateRule(User user){
estemplate.term("name",user.getId());
}
}
@[TOC](@Elasticsearch,json與java代碼分離查詢)
@Elasticsearch是一種類似與Mybatis的查詢方式,不過相對應的是把xml查詢文件修改爲json文件,原因是elasticsearch的查詢方式是基於json的
首先說下json的規則,json文件名必須與接口的文件名相同,然後json的第一級是對應的方法,第二季有3個屬性,index對應索引位置,requestMethod請求方式,script對應腳本,對於需要替換的屬性,使用#{}標註(數字等在ais中同樣使用引號,負責#{}便不是json的格式了),然後使用@Elasticsearch只有3種返回結果,JSONObject,String,List<Entity>格式,對於正常的查找,我們使用list格式即可,其餘操作按情況而定。
另外在使用@Autowired時,ais之默認把接口名字的首字母小寫後注入爲bean,
比如接口名字爲FInd
則
@Autowired
Find find;
下面簡單看下它的幾個例子
@Elasticsearch
public interface UserJson {
List findName(String name);
List findIdName(String name,String id);
}
{
“findName”: {
“requestMethod”: “GET”,
“index”: “demo/_search”,
“script”: {
“query”: {
“wildcard”: {
“name”: {
“value”: “#{name}”
}
}
}
}
},
“findIdName”: {
"requestMethod": "GET",
"index": "demo/_search",
"script": {
"query": {
"bool": {
"must": [
{
"wildcard": {
"name": {
"value": "#{name}"
}
}
},
{
"term": {
"id": {
"value": "#{id}"
}
}
}
]
}
}
}
}
}
@Elasticsearch
public interface UserSenior {
List findSenior(User user);
List findSeniorTest(User user);
}
{
“findSenior”: {
“requestMethod”: “GET”,
“index”: “demo/_search”,
“script”: {
“query”: {
“bool”: {
“must”: [
{
“wildcard”: {
“name”: {
“value”: “#{name}”
}
}
},
{
“term”: {
“id”: {
“value”: “#{id}”
}
}
}
],
“must_not”: [
{
“range”: {
“age”: {
“gte”: “#{age}”
}
}
}
]
}
}
}
},
“findSeniorTest”: {
“requestMethod”: “GET”,
“index”: “demo/_search”,
“script”: {
“query”: {
“bool”: {
“must”: [
{
“wildcard”: {
“name”: {
“value”: “#{name}”
}
}
},
{
“term”: {
“id”: {
“value”: “#{id}”
}
}
}
],
“must_not”: [
{
“range”: {
“age”: {
“gte”: “#{age}”
}
}
}
]
}
},
“from”: “#{pageFrom}”,
“size”: “#{pageSize}”
}
}
}
@RestController
public class FindJson {
@Autowired
UserJson userJson;
@Autowired
UserSenior userSenior;
@RequestMapping("/findName")
public List<User> findName(String name){
return userJson.findName(name);
}
@RequestMapping("/findIdName")
public List<User> findIdName(String name,String id){
return userJson.findIdName(name,id);
}
@RequestMapping("/findSenior")
public List<User> findSenior(User user){
return userSenior.findSenior(user);
}
@RequestMapping("/findSeniorTest")
public List<User> findSeniorTest(User user){
return userSenior.findSeniorTest(user);
}
}
@[TOC](kibana內容的直接引用)
@Elasticsearch可以滿足你的所有操作,但是當你的操作內容過於簡單時候你可以選擇EsteplateCuston,它是@Elasticsearch的java代碼格式
你可能發現,我們是將所以kibana的代碼複製出來,然後將對應的字段值替換成#{}
另外,EsteplateCuston裏的方法當然不只有一種,它還可以單純的去做執行,和一部分異步操作等功能(異步並不完善但可以使用)
它方法中的參數:
index:索引
requestMethod:請求方式
tClass:實體類.class
entity: 對應實體類
url:請求路徑
@RestController
public class FindCustom {
@Autowired
EstemplateCustom estemplateCustom;
@RequestMapping("/findCustom")
public List<User> findCustom(User user) throws IllegalAccessException, NoSuchFieldException, IOException {
String script="GET demo/_search\n" +
"{\n" +
" \"query\": {\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" {\n" +
" \"wildcard\": {\n" +
" \"name\": {\n" +
" \"value\": \"#{name}\"\n" +
" }\n" +
" }\n" +
" },\n" +
" {\n" +
" \"term\": {\n" +
" \"id\": {\n" +
" \"value\": \"#{id}\"\n" +
" }\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"must_not\": [\n" +
" {\n" +
" \"range\": {\n" +
" \"age\": {\n" +
" \"gte\": #{age}\n" +
" }\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n" +
" \"from\": \"#{pageFrom}\",\n" +
" \"size\": \"#{pageSize}\"\n" +
"}";
return estemplateCustom.excute(script,user);
}
}
@ELASTICSEARCHASYNC
@ElasticsearchAsync是@Elasticserach的異步操作,他們的使用方式相同但是@ElasticsearchAsync的操作並不太穩定和完善,我會及時完善對應的功能。