服务端技术实战系列——ElasticSearch篇

一、基本操作

[if !supportLists]1. [endif]创建索引(字段属性为not_analyzed类型)

POST   10.120.135.104:9200/analysis_engine

   {

    "mappings" : {

        "fa_test" : {

            "properties" : {

                "interface_name" : {

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "request_params":{

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "trace_id":{

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "request_type":{

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "request_mode":{

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "version":{

                    "type" : "integer",

                    "index" : "not_analyzed"

                },

                "response_content":{

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "preInterfaceInfo":{

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "nextInterfaceInfo":{

                    "type" : "string",

                    "index" : "not_analyzed"

                },

                "request_time":{

                    "type" : "string",

                    "index" : "not_analyzed"

                }

            }

        }

    }

}


说明:

Index: analysis_engine(相当于数据库的概念)

type: fa_test(相当于数据库里的表概念)


[if !supportLists]2. [endif]插入文档

POST  10.120.135.104:9200/tester/tester/1

{

"interface_name": "fa.163.com:10007/favicon.ico",

"request_params": "",

    "trace_id": "2b8faa0e2d2c4f31ba5f36155dc1de22",

    "request_type": "GET",

    "request_mode": "SOURCE",

    "version": 1,

    "response_content":"aaaaaa",

    "preInterfaceInfo": null,

    "nextInterfaceInfo": null,

    "request_time": 1533627190823

}


[if !supportLists]3. [endif]搜索最大id值

POST  10.120.135.104:9200/analysis_engine/fa_test/_search

{

"_source":false,

"sort":

  {

    "_uid": {

      "order": "desc"

    }

  },

"size":1

}


[if !supportLists]4. [endif]统计表中数据总条数

GET  10.120.135.104:9200/analysis_engine/fa_test/_count


[if !supportLists]5. [endif]新增一列

POST  10.120.135.104:9200/analysis_engine/_mapping/fa_test

{

"properties":{

"version":{"type":"integer"}

}

}

新增的列名为version,类型为integer


[if !supportLists]6. [endif]按条件搜索并排序

POST  10.120.135.104:9200/analysis_engine/fa_test/_search

{

"query": {

"term": {

"interface_name": "ddd"

}

},

"sort": {

"version": {

"order": "desc"

}

}

}

[if !supportLists]7. [endif]按条件搜索

POST  10.120.135.104:9200/analysis_engine/fa_test/_search

{

"query": {

"match": {

"interface_name": "fa.163.com:10007/interfaces/activePush/getToken.do"

}

}

}


[if !supportLists]8. [endif]搜索全量数据

GET  10.120.135.104:9200/analysis_engine/fa_test/_search?size=10000


[if !supportLists]9. [endif]按某个字段名和字段值精准搜索

POST  10.120.135.104:9200/analysis_engine/fa_test/_search

{

    "query" : {

        "constant_score" : {

            "filter" : {

                "term" : {

                    "interface_name" : "fa.163.com:10007/interfaces/activePush/getToken.do"

                }

            }

        }

    }

}


[if !supportLists]10. [endif]根据id查询

POST  http://10.120.135.104:9200/analysis_engine/_mget?pretty

{

"ids":["1","2"]

}

或者:

GET  http://10.120.135.104:9200/analysis_engine/fa_test/1


[if !supportLists]11. [endif]删除索引

DELETE  10.120.135.104:9200/analysis_engine


[if !supportLists]12. [endif]根据id删除

DELETE  10.120.135.104:9200/analysis_engine/fa_test/10


[if !supportLists]13. [endif]按范围搜索

POST  10.120.135.104:9200/analysis_engine/fa_test/_search

{

"query": {

"range": {

"request_time": {

"gt": 1533714426135,"lt":1533714426139

}

}

},

"size":10000

}


[if !supportLists]14. [endif]按范围搜索并返回指定的字段值(必须指定size否则默认只返回10条数据

POST  10.120.135.104:9200/analysis_engine/fa_test/_search

{

"_source":{

"include":["trace_id","request_mode","request_time"]

},

"query": {

"range": {

"request_time": {

"gt": 1533714416135,"lt":1533714446139

}

}

},

"size":10000

}


[if !supportLists]15. [endif]多条件查询(bool查询)

POST  10.120.135.104:9200/analysis_engine/fa_test/_search?size=10000

{

"query":

{

    "bool": {

        "must": { "term": { "trace_id": "3b8faa0e2d2c4f31ba5f36155dc1de22" }},

        "must": { "term": { "request_time": "2633627190249" }}

    }

},

"size":100

}



[if !supportLists]二、[endif]JAVA API

[if !supportLists]1. [endif]ES连接器

/**

 * AnalysisEngine——EsConnector

 *

 * @author ZhangChi

 * @date 2018年6月25日---下午8:11:01

 * @version 1.0

 */

@Service("esConnector")

public class EsConnector {


private static Logger logger = LoggerFactory.getLogger("EsConnector");


private static RestClient restClient;


@Value("${elasticSearch.host}")

private String host;

@Value("${elasticSearch.port}")

private int port;

@PostConstruct

public void initConnection() {

HttpHost[] httpHosts = new HttpHost[1];

httpHosts[0] = new HttpHost(host, port);

restClient = RestClient.builder(httpHosts).build();

}


public Response request(EsMethod method, String endPoint) {

try {

return restClient.performRequest(method.toString(), endPoint);

} catch (IOException e) {

logger.error("[ESConnector] 请求失败! method={},endPoint={}", method.toString(), endPoint, e);

}

return null;

}


public Response request(EsMethod method, String endPoint, String requetBody) {

try {

HttpEntity entity = new StringEntity(requetBody, ContentType.APPLICATION_JSON);


return restClient.performRequest(method.toString(), endPoint, Collections.emptyMap(), entity,

new Header[0]);

} catch (IOException e) {

logger.error("[ESConnector] 请求失败! method={},endPoint={},requetBody={}",

new Object[] { method.toString(), endPoint, requetBody, e });

}

return null;

}


public Response request(EsMethod method, String db, String table, String _id) {

try {

String endPoint = "";

if (db != null) {

endPoint = endPoint + "/" + db;

}

if (table != null) {

endPoint = endPoint + "/" + table;

}

if (table != null) {

endPoint = endPoint + "/" + _id;

}

return restClient.performRequest(method.toString(), endPoint, new Header[0]);

} catch (IOException e) {

logger.error("[ESConnector] method={},db={},table={},id={}",

new Object[] { method.toString(), db, table, _id, e });

}

return null;

}


public RestClient getClient() {

return restClient;

}


public Response clientRequest(EsMethod method, String db, String table, String _id, Map params,

HttpEntity entity, Header... headers) {

Response indexResponse = null;

try {

indexResponse = restClient.performRequest(method.toString(), "/" + db + "/" + table + "/" + _id, params,

entity, headers);

} catch (IOException e) {

logger.error("[ESConnector] 请求失败! method={},db={},table={},_id={},entity={}",

new Object[] { method.toString(), db, table, _id, JsonUtils.toJson(entity), e });

}

return indexResponse;

}

}

[if !supportLists]2. [endif]ES索引操作

/**

 * AnalysisEngine——EsIndexServiceImpl

 *

 * @author ZhangChi

 * @date 2018年7月2日---上午10:59:17

 * @version 1.0

 */

@Service("esIndexServiceImpl")

public class EsIndexServiceImpl implements EsIndexService {


@Autowired

private EsConnector esConnector;


public Response createCommonIndexTemplate() {

try {

XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("template", "analysis_engine*")

.field("order", 0).startObject("mappings").startObject("_default_").startObject("_all")

.field("enabled", false).endObject().startArray("dynamic_templates").startObject()

.startObject("strings_ik").field("match_mapping_type", "string").field("match", "content_*")

.startObject("mapping").field("type", "string").field("index", "analyzed")

.field("analyzer", "ik_max_word").field("search_analyzer", "ik_max_word").endObject().endObject()

.endObject().startObject().startObject("strings").field("match_mapping_type", "string")

.startObject("mapping").field("type", "string").field("index", "not_analyzed").endObject()

.endObject().endObject().endArray().endObject().endObject().endObject();


return createIndexTemplate("analysis_engine", builder);

} catch (Exception e) {

LogConstant.runLog.error("[CreateIndexTemplate] error : ", e);

e.printStackTrace();

}

return null;

}


public Response createIndexTemplate(String templateName, XContentBuilder builder) {

try {

return createIndexTemplate(templateName, builder.string());

} catch (Exception e) {

LogConstant.runLog.error("[EsIndexServiceImpl]create index template : ", e);

e.printStackTrace();

}

return null;

}


/*创建索引模板*/

@Override

public Response createIndexTemplate(String templateName, String template) {

try {

String queryStr = templateExist(templateName);

if (StringUtils.isEmpty(queryStr)) {

LogConstant.runLog.info("[index template]" + template);


HttpEntity entity = new NStringEntity(template, ContentType.APPLICATION_JSON);

return this.esConnector.getClient().performRequest("PUT", "/_template/" + templateName,

Collections.emptyMap(), entity, new Header[0]);

}

LogConstant.runLog.info("Create Index Success!");

} catch (Exception e) {

LogConstant.runLog.error("[EsIndexServiceImpl] Create Index Template : ", e);

e.printStackTrace();

}

return null;

}


/*删除索引*/

@Override

public int deleteIndex(String indexName) {

try {

if (indexExist(indexName).booleanValue()) {

Response response = this.esConnector.request(EsMethod.DELETE, indexName);

int statusCode = response.getStatusLine().getStatusCode();

if (statusCode == 200) {

return 1;

}

} else {

LogConstant.runLog.info("[Es deleteIndex] " + indexName + "not exists!");

return 0;

}

} catch (Exception e) {

LogConstant.runLog.warn("[ES deleteIndex]", e);

}

return 0;

}


private String templateExist(String templateName) {

Response response = null;

try {

response = this.esConnector.getClient().performRequest("GET", "/_template/" + templateName,

Collections.emptyMap(), new Header[0]);

return EntityUtils.toString(response.getEntity());

} catch (Exception e) {

}

return null;

}


private Boolean indexExist(String indexName) {

Response response = this.esConnector.request(EsMethod.HEAD, indexName);

try {

if (response.getStatusLine().getStatusCode() == 200) {

return Boolean.valueOf(true);

}

} catch (Exception e) {

LogConstant.runLog.warn("[indexExist]", e);

}

return Boolean.valueOf(false);

}

}


[if !supportLists]3. [endif]ES文档操作

ES文档操可以基于ES连接器,是在其基础上的封装

/* 插入 */

@Override

public Response insert(String index, String type, String _id, Object entity) {

/**

 * 对应关系:index-db,type-table

 */

return insert(index, type, _id, JsonUtils.toJson(entity));

}


private Response insert(String db, String table, String _id, String json) {

LogUtils.log().debug("[DocumentServiceImp.insert],index={},type={},id={}", new Object[] { db, table, _id });

HttpEntity entity = new NStringEntity(json, ContentType.APPLICATION_JSON);

return esConnector.clientRequest(EsMethod.POST, db, table, _id, Collections.emptyMap(), entity, new Header[0]);

}


/* 删除 */

@Override

public Response deleteById(String db, String table, String id) {

LogUtils.log().info("[DocumentServiceImp.deleteById],index={},type={},id={}", new Object[] { db, table, id });

return esConnector.request(EsMethod.DELETE, db, table, id);

}


/* 查询 */

@Override

public Response queryById(String db, String table, String id) {

LogUtils.log().info("[DocumentServiceImp.queryById],index={},type={},id={}", new Object[] { db, table, id });

return esConnector.request(EsMethod.GET, db, table, id);

}


/* 统计 */

@Override

public Response countByIndex(String indexName) {

return esConnector.request(EsMethod.GET, indexName + "/_count");

}

[if !supportLists]4. [endif]ES搜索操作

ES搜索操可以基于ES连接器和ES文档操作,是在其基础上的封装

/* 类sql搜索*/

@Override

public String queryByQuerySql(String db, String table, String querysql) {

// TODO Auto-generated method stub

LogUtils.log().debug("[SearchServiceImpl.queryByQuerySql] db={},table={},querybody={}",

new Object[] { db, table, querysql });

Response response = esDocumentService.queryByQuerySql(db, table, querysql);

return EsUtils.parseResponse2Str(response);

}


/**

 * 类sql搜索,返回Hits 入参clazz: ResponseHits.class

 */

@Override

public  Hits queryByQuerySql(String db, String table, String querysql, Class clazz) {

LogUtils.log().debug("[SearchServiceImpl.queryByQuerySql] db={},table={},querybody={}",

new Object[] { db, table, querysql });

Response response = esDocumentService.queryByQuerySql(db, table, querysql);

return EsUtils.parseResponse(response, clazz);

}


/**

 * 全量查询

 */

@Override

public String queryAllData(String db, String table, String query, String time, String scroll_id) {

// TODO Auto-generated method stub

StringBuilder endPoint = new StringBuilder();

endPoint.append("/").append(db).append("/").append(table).append("/_search?scroll=").append(scroll_id);

Response response = esConnector.request(EsMethod.GET, endPoint.toString(), query);

return EsUtils.parseResponse2Str(response);

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容

  • Overview The ccxt library is a collection of available cr...
    郭蝈儿蝈儿阅读 3,694评论 0 1
  • 文章图片上传不正常,如需文档,可联系微信:1017429387 目录 1 安装... 4 1.1 配置探针... ...
    Mrhappy_a7eb阅读 6,296评论 0 5
  • 12月1日,天气晴好,我们的亲子日记在继续记录着。亲子日记也要爸爸来参加噢!看,这父子俩共同探讨知识的过程。...
    扬帆起航__爱之语阅读 659评论 0 1