需求
需要使用精確搜索和全文搜索,找到相關(guān)數(shù)據(jù)的ID或者唯一的名稱。使用Elastic Search建立搜索引擎。
Restful Api 需求
暴露給用戶的是 Restful Api。
有以下場(chǎng)景:
- 用戶插入數(shù)據(jù)。
- 用戶更新價(jià)格。
- 用戶根據(jù)Tag查詢并分頁(yè)展示。
- 用戶根據(jù)ID查詢數(shù)據(jù)詳細(xì)信息。
Restful接口規(guī)范
1.插入數(shù)據(jù)到ElasticSearch
url:/api/v1/dataset
method:POST
請(qǐng)求:
{
"Name":"上海第九人民醫(yī)院青少年骷髏腿數(shù)據(jù)",
"TAG1":"青少年疾病",
"TAG2":"骨科",
"TAG3":"上海第九人民醫(yī)院青少年骷髏腿數(shù)據(jù)1949年到2004年",
"StartTimeCollected":"20110404",
"EndTimeCollected":"20120909",
"Price":"0.1",
"CoinType":"ong"
}
| Field Name | Type | Description |
|---|---|---|
| Name | String | 標(biāo)識(shí)一條數(shù)據(jù),用戶插入數(shù)據(jù)的時(shí)候指定 |
| ID | String | 標(biāo)識(shí)一條數(shù)據(jù),查詢系統(tǒng)生成 |
| Tag1 | String | 大類別 |
| Tag2 | String | 小類別 |
| Tag3 | Text | 描述,屬性 |
| Price | String | 價(jià)格 |
| CoinType | String | 貨幣種類 |
| StartTimeCollected | Date | UTC時(shí)間,數(shù)據(jù)開始采集的時(shí)間 |
| EndTimeCollected | Date | UTC時(shí)間,數(shù)據(jù)結(jié)束采集的時(shí)間 |
響應(yīng):
{
"error":0,
"desc":"SUCCESS",
"result": "ID"
}
| Field Name | Type | Description |
|---|---|---|
| error | int | 錯(cuò)誤碼 |
| desc | String | 成功為SUCCESS,失敗為錯(cuò)誤描述 |
| result | String | 成功返回?cái)?shù)據(jù)ID,失敗返回"" |
2.更新數(shù)據(jù)到ElasticSearch
url:/api/v1/dataset
method:POST
請(qǐng)求:
{
"ID":"0000000001",
"Name":"上海第九人民醫(yī)院青少年骷髏腿數(shù)據(jù)",
"TAG1":"青少年疾病",
"TAG2":"骨科",
"TAG3":"上海第九人民醫(yī)院青少年骷髏腿數(shù)據(jù)1949年到2004年",
"StartTimeCollected":"20110404",
"EndTimeCollected":"20120909",
"Price":"0.1",
"CoinType":"ong"
}
數(shù)據(jù)格式和插入的一樣。
響應(yīng):
{
"error":0,
"desc":"SUCCESS",
"result": "ID"
}
| Field Name | Type | Description |
|---|---|---|
| error | int | 錯(cuò)誤碼 |
| desc | String | 成功為SUCCESS,失敗為錯(cuò)誤描述 |
| result | String | 成功返回?cái)?shù)據(jù)ID,失敗返回"" |
3.查詢數(shù)據(jù),分頁(yè)返回
url:/api/v1/dataset?{name=}&{tag1=}&{tag2=}&{tag3=}&&{page_index=}&{page_offset=}
method:Get
返回分頁(yè)數(shù)據(jù)。tag1,tag2,name,id都是精確匹配,tag3是全文檢索。
響應(yīng):
{
"error":0,
"desc":"SUCCESS",
"result": {
"total": "",
"records": []
}
}
| Field Name | Type | Description |
|---|---|---|
| error | int | 錯(cuò)誤碼 |
| desc | String | 成功為SUCCESS,失敗為錯(cuò)誤描述 |
| result | Object | 返回分頁(yè)數(shù)據(jù) |
| total | String | 總頁(yè)數(shù) |
| records | Array | Array里面每個(gè)數(shù)據(jù)和插入的數(shù)據(jù)一個(gè)格式 |
4. 根據(jù)ID返回?cái)?shù)據(jù)
url:/api/v1/dataset/id
method:Get
響應(yīng):
{
"error":0,
"desc":"SUCCESS",
"result": {
//和插入的數(shù)據(jù)一樣
}
}
5. 權(quán)限
目前Restful API沒有設(shè)計(jì)權(quán)限系統(tǒng),由使用代碼的第三方自己實(shí)現(xiàn)
Elastic Search Java API
1. 創(chuàng)建Index
索引,類似數(shù)據(jù)庫(kù)
public static boolean createIndex(String index) {
if (!isIndexExist(index)) {
LOGGER.info("Index is not exits!");
}
CreateIndexResponse indexresponse = client.admin().indices().prepareCreate(index).execute().actionGet();
LOGGER.info("執(zhí)行建立成功?" + indexresponse.isAcknowledged());
return indexresponse.isAcknowledged();
}
/**
* 判斷索引是否存在
*
* @param index
* @return
*/
public static boolean isIndexExist(String index) {
IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();
if (inExistsResponse.isExists()) {
LOGGER.info("Index [" + index + "] is exist!");
} else {
LOGGER.info("Index [" + index + "] is not exist!");
}
return inExistsResponse.isExists();
}
2. 插入的數(shù)據(jù)
數(shù)據(jù)格式:
| 列 | 類型 | 作用 |
|---|---|---|
| Name | String | 標(biāo)識(shí)一條數(shù)據(jù),用戶插入數(shù)據(jù)的時(shí)候指定 |
| ID | String | 標(biāo)識(shí)一條數(shù)據(jù),查詢系統(tǒng)生成 |
| Tag1 | String | 大類別 |
| Tag2 | String | 小類別 |
| Tag3 | Text | 描述,屬性 |
| Price | String | 價(jià)格 |
| CoinType | String | 貨幣種類 |
| StartTimeCollected | Date | UTC時(shí)間,數(shù)據(jù)開始采集的時(shí)間 |
| EndTimeCollected | Date | UTC時(shí)間,數(shù)據(jù)結(jié)束采集的時(shí)間 |
三級(jí)標(biāo)簽搜索方式:
| 標(biāo)簽名稱 | 標(biāo)簽優(yōu)先級(jí) | 查詢方式 |
|---|---|---|
| Tag1 | 高 | 精確匹配 |
| Tag2 | 中 | 精確匹配 |
| Tag3 | 低 | 全文檢索 |
還有其他的屬性,存貯在Mysql,Elastic Search主要負(fù)責(zé)對(duì)上面Tag進(jìn)行搜索。
/**
* 數(shù)據(jù)添加
*
* @param jsonObject 要增加的數(shù)據(jù)
* @param index 索引,類似數(shù)據(jù)庫(kù)
* @param type 類型,類似表
* @param id 數(shù)據(jù)ID
* @return
*/
public static String addData(JSONObject jsonObject, String index, String type, String id) {
IndexResponse response = client.prepareIndex(index, type, id).setSource(jsonObject).get();
LOGGER.info("addData response status:{},id:{}", response.status().getStatus(), response.getId());
return response.getId();
}
3. 更新或者刪除數(shù)據(jù)
- 對(duì)插入
Elastic Search的index,document,type進(jìn)行更新。 - 通過ID刪除數(shù)據(jù)。
/**
* 通過ID刪除數(shù)據(jù)
*
* @param index 索引,類似數(shù)據(jù)庫(kù)
* @param type 類型,類似表
* @param id 數(shù)據(jù)ID
*/
public static void deleteDataById(String index, String type, String id) {
DeleteResponse response = client.prepareDelete(index, type, id).execute().actionGet();
LOGGER.info("deleteDataById response status:{},id:{}", response.status().getStatus(), response.getId());
}
/**
* 通過ID 更新數(shù)據(jù)
*
* @param jsonObject 要增加的數(shù)據(jù)
* @param index 索引,類似數(shù)據(jù)庫(kù)
* @param type 類型,類似表
* @param id 數(shù)據(jù)ID
* @return
*/
public static void updateDataById(JSONObject jsonObject, String index, String type, String id) {
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index(index).type(type).id(id).doc(jsonObject);
client.update(updateRequest);
}
4. 查詢數(shù)據(jù)并分頁(yè)
/**
* 使用分詞查詢,并分頁(yè)
*
* @param index 索引名稱
* @param type 類型名稱,可傳入多個(gè)type逗號(hào)分隔
* @param startPage 當(dāng)前頁(yè)
* @param pageSize 每頁(yè)顯示條數(shù)
* @param query 查詢條件
* @param fields 需要顯示的字段,逗號(hào)分隔(缺省為全部字段)
* @param sortField 排序字段
* @param highlightField 高亮字段
* @return
*/
public static EsPage searchDataPage(String index, String type, int startPage, int pageSize, QueryBuilder query, String fields, String sortField, String highlightField) {