Elasticsearch是目前最受欢迎的搜索引擎之一,伙伴们知道它的原理和使用方法是什么吗? 今天谈谈其原理和基本使用方法吧。
一. es原理介绍
我们知道,Apache Lucene可以说是当今最先进、最高效的开源搜索引擎框架。 但是,如果您试图在基于Java的企业项目中直接集成Apache
Lucene需要将提供的功能进一步封装到Java API中,成本太高且流程复杂。 可以使用像Apache这样高效、开源的其他产品
Solr和Elasticsearch。
Elasticsearch是基于Apache Lucene构建的分布式rest风格的搜索数据分析引擎,用于分析Apache和
与Solr相比,主要有以下优点:
-随着数据量的增加,Solr逐渐变慢,但Elasticsearch有明显的好处。
-如果实时搜索(在索引时进行搜索),则Solr会生成IO块,Elasticsearch的性能会更快。
由于这些因素,Elasticsearch特别适合于新的实时搜索APP应用程序场景,如大型internet B2C项目。
索引
Elasticsearch索引(index )是组织数据的逻辑命名空间。 Elasticsearch索引通常有一个或多个片。 默认值为5。 瓷砖是实际存储数据的Lucene索引,它本身就是搜索引擎。 每个分片可以有零个或多个“复制”。 默认值为1。 Elasticsearch索引还具有“类型”,用户可以在逻辑上对索引中的数据进行分区。 Elasticsearch索引中特定“类型”下的所有文档具有相同的属性。
取消索引
Elasticsearch最强大的功能是为每个字段提供倒排索引。 查询时没有索引就不用担心不可用。 什么是倒排索引? 举个简单的例子:
每一行都是文档,每个文档都有文档ID。 在中,为这些文档创建的倒排索引如下:
如您所见,每个字段都有倒排索引,每个字段都有自己的倒排索引。 25、32等称为term,类似[1、3]的称为posting list。
联合索引
如何使用联盟索引查询
使用Skip List数据结构,同时遍历多个term的posting list,并相互skip
-使用bitset数据结构为多个term分别计算bitset,并对bitset执行AN操作
二. es的基本使用方法
1 )、创建clientpublicelasticsearchservice (字符串IP地址,导入)
{
客户端=newtransportclient (
. addtransportaddress (newinetsockettransportaddress ) IP地址
、端口;
}
上面是传输客户端。
eS中的客户端比较:
传输客户端—使用netty线程池将套接字连接到ES群集的轻量客户端。 它本身不加入集群,而是被视为请求。
节点客户端—该客户端节点本身也是一个ES节点,加入群集并类似于其他ElasticSearch节点。 频繁地打开/关闭此类节点
客户端使集群产生“噪声”。
2 )、索引和类型信息的创建/删除/索引
publicvoidcreateIndex (
{
client.admin (
. indices () )
. create(newcreateindexrequest (索引名称) )
. actionGet (;
}
//清除所有索引
publicvoiddeleteIndex (
{
indicesexistsresponseindicesexistsresponse=client.admin (
. indices () )
. exists (newindicesexistsrequest (new字符串[ ]
{
索引名称
() )
. actionGet (;
if (indicesexistsresponse.is exists ()
{
client.admin (
. indices () )
. delete(newdeleteindexrequest (索引名称) )
. 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("_all")
.field("enabled", false)
.endObject()
.startObject("properties")
.startObject(IDFieldName)
.field("type", "long")
.endObject()
.startObject(SeqNumFieldName)
.field("type", "long")
.endObject()
.startObject(IMSIFieldName)
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
.startObject(IMEIFieldName)
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
.startObject(DeviceIDFieldName)
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
.startObject(OwnAreaFieldName)
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
.startObject(TeleOperFieldName)
.field("type", "string")
.field("index", "not_analyzed")
.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());
}
}
3)、索引数据// 批量索引数据
public void indexHotSpotDataList(List dataList)
{
if (dataList != null)
{
int size = dataList.size();
if (size > 0)
{
BulkRequestBuilder bulkRequest = client.prepareBulk();
for (int i = 0; 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 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 getSearchData(QueryBuilder queryBuilder)
{
List 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 getSearchDataByScrolls(QueryBuilder queryBuilder)
{
List 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;
}
那么以上就是关于elasticsearch原理的所有内容了,如果还想要了解更多java架构师相关信息,就请快快关注本网站吧。
推荐阅读: