本文部分转载于:

http://www.cnblogs.com/luxiaoxun/p/4869509.html

ElasticSearch的基本用法与集群搭建

 一、简介

ElasticSearch和Solr都是基于Lucene的搜索引擎,不过ElasticSearch天生支持分布式,而Solr是4.0版本后的SolrCloud才是分布式版本,Solr的分布式支持需要ZooKeeper的支持。

这里有一个详细的ElasticSearch和Solr的对比:http://solr-vs-elasticsearch.com/

二、基本用法

Elasticsearch集群可以包含多个索引(indices),每一个索引可以包含多个类型(types),每一个类型包含多个文档(documents),然后每个文档包含多个字段(Fields),这种面向文档型的储存,也算是NoSQL的一种吧。

ES比传统关系型数据库,对一些概念上的理解:

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields

从创建一个Client到添加、删除、查询等基本用法:

1、创建Client

public ElasticSearchService(String ipAddress, int port) {
client = new TransportClient()
.addTransportAddress(new InetSocketTransportAddress(ipAddress,
port));
}

这里是一个TransportClient。

ES下两种客户端对比:

TransportClient:轻量级的Client,使用Netty线程池,Socket连接到ES集群。本身不加入到集群,只作为请求的处理。

Node Client:客户端节点本身也是ES节点,加入到集群,和其他ElasticSearch节点一样。频繁的开启和关闭这类Node Clients会在集群中产生“噪音”。

2、创建/删除Index和Type信息

 // 创建索引
public void createIndex() {
client.admin().indices().create(new CreateIndexRequest(IndexName))
.actionGet();
} // 清除所有索引
public void deleteIndex() {
IndicesExistsResponse indicesExistsResponse = client.admin().indices()
.exists(new IndicesExistsRequest(new String[] { IndexName }))
.actionGet();
if (indicesExistsResponse.isExists()) {
client.admin().indices().delete(new DeleteIndexRequest(IndexName))
.actionGet();
}
} // 删除Index下的某个Type
public void deleteType(){
client.prepareDelete().setIndex(IndexName).setType(TypeName).execute().actionGet();
} // 定义索引的映射类型
public void defineIndexTypeMapping() {
try {
XContentBuilder mapBuilder = XContentFactory.jsonBuilder();
mapBuilder.startObject()
.startObject(TypeName)
.startObject("properties")
.startObject(IDFieldName).field("type", "long").field("store", "yes").endObject()
.startObject(SeqNumFieldName).field("type", "long").field("store", "yes").endObject()
.startObject(IMSIFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
.startObject(IMEIFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
.startObject(DeviceIDFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
.startObject(OwnAreaFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
.startObject(TeleOperFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
.startObject(TimeFieldName).field("type", "date").field("store", "yes").endObject()
.endObject()
.endObject()
.endObject(); PutMappingRequest putMappingRequest = Requests
.putMappingRequest(IndexName).type(TypeName)
.source(mapBuilder);
client.admin().indices().putMapping(putMappingRequest).actionGet();
} catch (IOException e) {
log.error(e.toString());
}
}

这里自定义了某个Type的索引映射(Mapping),默认ES会自动处理数据类型的映射:针对整型映射为long,浮点数为double,字符串映射为string,时间为date,true或false为boolean。

注意:针对字符串,ES默认会做“analyzed”处理,即先做分词、去掉stop words等处理再index。如果你需要把一个字符串做为整体被索引到,需要把这个字段这样设置:field("index", "not_analyzed")。

详情参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping-intro.html

个人注:

设置mapping信息 这段代码是在ES中的索引库index和类型都已经建立完之后,再向type中插入数据之前设置要插入数据对应的mappings信息...

如果给一个还没有创建的索引库,类型 设置mapping信息 可以参考如下代码:

也可以实现判断一下这个索引库index 或者指定索引库index对应的类型type到底是否存在...再设置mapping信息.

注意:插入数据之后是无法修改索引库对应的mapping信息的...只能删了重新创建. 如下部分我在项目中使用的代码:

     public void setMappings(){
//mappings
try {
XContentBuilder mappings = XContentFactory.jsonBuilder();
mappings.startObject()
.startObject(EsUtil.mmobjectTypename)
.startObject("properties")
.startObject("name").field("type","text").endObject()
.startObject("search_createtime").field("type","text").endObject()
.endObject()
.endObject()
.endObject();
boolean exists = transportClient.admin().indices()
.prepareExists(EsUtil.indexname)
.execute().actionGet().isExists();
if(exists){
PutMappingRequest putMappingRequest = Requests.
putMappingRequest(EsUtil.indexname).type(EsUtil.mmobjectTypename)
.source(mappings);
transportClient.admin().indices().putMapping(putMappingRequest).actionGet();
}else{
CreateIndexRequestBuilder prepareCreate = transportClient.admin().indices().prepareCreate(EsUtil.indexname);
prepareCreate.addMapping(EsUtil.mmobjectTypename, mappings).execute().actionGet();
}
} catch (IOException e) {
e.printStackTrace();
}
}

关于设置mappings信息还可以参考如下:

http://stackoverflow.com/questions/23552845/configure-elasticsearch-mapping-with-java-api

3、索引数据

 // 批量索引数据
public void indexHotSpotDataList(List<Hotspotdata> dataList) {
if (dataList != null) {
int size = dataList.size();
if (size > 0) {
BulkRequestBuilder bulkRequest = client.prepareBulk();
for (int i = 0; i < size; ++i) {
Hotspotdata data = dataList.get(i);
String jsonSource = getIndexDataFromHotspotData(data);
if (jsonSource != null) {
bulkRequest.add(client
.prepareIndex(IndexName, TypeName,
data.getId().toString())
.setRefresh(true).setSource(jsonSource));
}
} BulkResponse bulkResponse = bulkRequest.execute().actionGet();
if (bulkResponse.hasFailures()) {
Iterator<BulkItemResponse> iter = bulkResponse.iterator();
while (iter.hasNext()) {
BulkItemResponse itemResponse = iter.next();
if (itemResponse.isFailed()) {
log.error(itemResponse.getFailureMessage());
}
}
}
}
}
} // 索引数据
public boolean indexHotspotData(Hotspotdata data) {
String jsonSource = getIndexDataFromHotspotData(data);
if (jsonSource != null) {
IndexRequestBuilder requestBuilder = client.prepareIndex(IndexName,
TypeName).setRefresh(true);
requestBuilder.setSource(jsonSource)
.execute().actionGet();
return true;
} return false;
} // 得到索引字符串
public String getIndexDataFromHotspotData(Hotspotdata data) {
String jsonString = null;
if (data != null) {
try {
XContentBuilder jsonBuilder = XContentFactory.jsonBuilder();
jsonBuilder.startObject().field(IDFieldName, data.getId())
.field(SeqNumFieldName, data.getSeqNum())
.field(IMSIFieldName, data.getImsi())
.field(IMEIFieldName, data.getImei())
.field(DeviceIDFieldName, data.getDeviceID())
.field(OwnAreaFieldName, data.getOwnArea())
.field(TeleOperFieldName, data.getTeleOper())
.field(TimeFieldName, data.getCollectTime())
.endObject();
jsonString = jsonBuilder.string();
} catch (IOException e) {
log.equals(e);
}
} return jsonString;
}

ES支持批量和单个数据索引。

4、查询获取数据

 // 获取少量数据100个
private List<Integer> getSearchData(QueryBuilder queryBuilder) {
List<Integer> ids = new ArrayList<>();
SearchResponse searchResponse = client.prepareSearch(IndexName)
.setTypes(TypeName).setQuery(queryBuilder).setSize(100)
.execute().actionGet();
SearchHits searchHits = searchResponse.getHits();
for (SearchHit searchHit : searchHits) {
Integer id = (Integer) searchHit.getSource().get("id");
ids.add(id);
}
return ids;
} // 获取大量数据
private List<Integer> getSearchDataByScrolls(QueryBuilder queryBuilder) {
List<Integer> ids = new ArrayList<>();
// 一次获取100000数据
SearchResponse scrollResp = client.prepareSearch(IndexName)
.setSearchType(SearchType.SCAN).setScroll(new TimeValue(60000))
.setQuery(queryBuilder).setSize(100000).execute().actionGet();
while (true) {
for (SearchHit searchHit : scrollResp.getHits().getHits()) {
Integer id = (Integer) searchHit.getSource().get(IDFieldName);
ids.add(id);
}
scrollResp = client.prepareSearchScroll(scrollResp.getScrollId())
.setScroll(new TimeValue(600000)).execute().actionGet();
if (scrollResp.getHits().getHits().length == 0) {
break;
}
} return ids;
}

这里的QueryBuilder是一个查询条件,ES支持分页查询获取数据,也可以一次性获取大量数据,需要使用Scroll Search。

5、聚合(Aggregation Facet)查询

 // 得到某段时间内设备列表上每个设备的数据分布情况<设备ID,数量>
public Map<String, String> getDeviceDistributedInfo(String startTime,
String endTime, List<String> deviceList) { Map<String, String> resultsMap = new HashMap<>(); QueryBuilder deviceQueryBuilder = getDeviceQueryBuilder(deviceList);
QueryBuilder rangeBuilder = getDateRangeQueryBuilder(startTime, endTime);
QueryBuilder queryBuilder = QueryBuilders.boolQuery()
.must(deviceQueryBuilder).must(rangeBuilder); TermsBuilder termsBuilder = AggregationBuilders.terms("DeviceIDAgg").size(Integer.MAX_VALUE)
.field(DeviceIDFieldName);
SearchResponse searchResponse = client.prepareSearch(IndexName)
.setQuery(queryBuilder).addAggregation(termsBuilder)
.execute().actionGet();
Terms terms = searchResponse.getAggregations().get("DeviceIDAgg");
if (terms != null) {
for (Terms.Bucket entry : terms.getBuckets()) {
resultsMap.put(entry.getKey(),
String.valueOf(entry.getDocCount()));
}
}
return resultsMap;
}

Aggregation查询可以查询类似统计分析这样的功能:如某个月的数据分布情况,某类数据的最大、最小、总和、平均值等。

详情参考:https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-aggs.html

三、集群配置

配置文件elasticsearch.yml

集群名和节点名:

#cluster.name: elasticsearch

#node.name: "Franz Kafka"

是否参与master选举和是否存储数据

#node.master: true

#node.data: true

分片数和副本数

#index.number_of_shards: 5
#index.number_of_replicas: 1

master选举最少的节点数,这个一定要设置为整个集群节点个数的一半加1,即N/2+1

#discovery.zen.minimum_master_nodes: 1

discovery ping的超时时间,拥塞网络,网络状态不佳的情况下设置高一点

#discovery.zen.ping.timeout: 3s

注意,分布式系统整个集群节点个数N要为奇数个!!

如何避免ElasticSearch发生脑裂(brain split):http://blog.trifork.com/2013/10/24/how-to-avoid-the-split-brain-problem-in-elasticsearch/

即使集群节点个数为奇数,minimum_master_nodes为整个集群节点个数一半加1,也难以避免脑裂的发生,详情看讨论:https://github.com/elastic/elasticsearch/issues/2488

四、Elasticsearch插件

1、elasticsearch-head是一个elasticsearch的集群管理工具:./elasticsearch-1.7.1/bin/plugin -install mobz/elasticsearch-head

2、elasticsearch-sql:使用SQL语法查询elasticsearch:./bin/plugin -u https://github.com/NLPchina/elasticsearch-sql/releases/download/1.3.5/elasticsearch-sql-1.3.5.zip --install sql

github地址:https://github.com/NLPchina/elasticsearch-sql

3、elasticsearch-bigdesk是elasticsearch的一个集群监控工具,可以通过它来查看ES集群的各种状态。

安装:./bin/plugin -install lukas-vlcek/bigdesk

访问:http://192.103.101.203:9200/_plugin/bigdesk/

4、elasticsearch-servicewrapper插件是ElasticSearch的服务化插件,

在https://github.com/elasticsearch/elasticsearch-servicewrapper下载该插件后,解压缩,将service目录拷贝到elasticsearch目录的bin目录下。

而后,可以通过执行以下语句安装、启动、停止ElasticSearch:

sh elasticsearch install

sh elasticsearch start

sh elasticsearch stop

参考:

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

http://stackoverflow.com/questions/10213009/solr-vs-elasticsearch

=============================================

java代码操作ES的settings配置信息

ES代码总结2的更多相关文章

  1. android opengl es代码功能

    /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Versi ...

  2. 最新的JavaScript核心语言标准——ES6,彻底改变你编写JS代码的方式!【转载+整理】

    原文地址 本文内容 ECMAScript 发生了什么变化? 新标准 版本号6 兑现承诺 迭代器和for-of循环 生成器 Generators 模板字符串 不定参数和默认参数 解构 Destructu ...

  3. 最新的ES 5.0路由算法底层实现

    http://www.cnblogs.com/bonelee/p/6078947.html 里分析了ES bulk实现,其中路由代码: ShardId shardId = clusterService ...

  4. ES bulk源码分析——ES 5.0

    对bulk request的处理流程: 1.遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话).指定的timestamp(如果没有带timestamp ...

  5. ES批量索引写入时的ID自动生成算法

    对bulk request的处理流程: 1.遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话).指定的timestamp(如果没有带timestamp ...

  6. OpenGL ES之GLFW窗口搭建

    概述 本章节主要总结如何使用GLFW来创建Opengl窗口.主要包括如下内容: OpenGl窗口创建介绍 GLFW Window版编译介绍 GLFW简单工程源码介绍 OpenGL窗口创建介绍 能用于O ...

  7. (转)规划从 OpenGL ES 2.0 到 Direct3D 的移植

    如果你移植 iOS 或 Android 平台中的游戏,那么你可能需要在 OpenGL ES 2.0 方面进行大量投资.如果你准备将你的图形管道代码库移动到 Direct3D 11 和 Windows ...

  8. 最新的JavaScript核心语言标准——ES6,彻底改变你编写JS代码的方式!

    原文地址 迁移到:http://www.bdata-cap.com/newsinfo/1741515.html 本文内容 ECMAScript 发生了什么变化? 新标准 版本号6 兑现承诺 迭代器和f ...

  9. 在Android中使用OpenGL ES进行开发第(三)节:绘制图形

    一.前期基础知识储备笔者计划写三篇文章来详细分析OpenGL ES基础的同时也是入门关键的三个点: ①OpenGL ES是什么?与OpenGL的关系是什么?——概念部分 ②使用OpenGLES绘制2D ...

随机推荐

  1. ubuntu16.04无法关机解决方法

    11 down vote   In my case these simple steps worked for me fine: Press Ctrl+Alt+T to go to a termina ...

  2. Vue、 React比较

    关键词:MVVM(Model-View-VIewModel)数据模型双向绑定.视图的数据变化会同时修改数据资源,数据资源的变化也会立刻反应到视图View上. 一.vue.js vue是一套构建用户界面 ...

  3. Typecho 插件开发基础

    <?php /** * 标题 插件说明 * * @package 添加标题 * @author Fan * @version 1.0.0 * @link http://cnblogs.com/f ...

  4. 微信分享接口 略缩图 php

    php插件下载地址:  https://files.cnblogs.com/files/fan-bk/jssdk_php.rar 提示:如果插件里面的jssdk.php函数 file_get_cont ...

  5. Atcoder Regular-074 Writeup

    C - Chocolate Bar 题面 There is a bar of chocolate with a height of H blocks and a width of W blocks. ...

  6. 1143 Lowest Common Ancestor

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...

  7. (区间dp 或 记忆化搜素 )Brackets -- POJ -- 2955

    http://poj.org/problem?id=2955 Description We give the following inductive definition of a “regular ...

  8. marven与Eclipse集成配置

    maven作为一个项目构建工具,在开发的过程中很受欢迎,可以帮助管理项目中的bao依赖问题,另外它的很多功能都极大的减少了开发的难度,下面来介绍maven的安装及与eclipse的集成. maven的 ...

  9. iOS中的序列帧动画

    UIImageView对象的有一个animationImages属性,将图片数组赋值给该属性即可.如图: 控制动画的播放方法是:[ ___  startAnimating]; 控制动画的停止方法是:[ ...

  10. ASP.NET MVC Bundles 合并压缩(js css)

    Chrome浏览器有并发的Http请求限制,Bundles可以将多个JS文件合并成一个文件并进行压缩,最终得到一个单文件的压缩包. 第一步:BundleConfig public class Bund ...