ElasticSearch基础应用
一、认识:
1、主要用途 做全文检索
2、特点:
(1)Es 全文检索框架 使用比lucene更简单
(2)ES支持集群 支持分布式
(3)支持JSON的操作
(4)一般大型全文检索都是用ES
(5)通过Restfull风格来操作ES
3、与Solr(重量级对手)比较:
(1)Solr 利用 Zookeeper 进行分布式管理,支持更多格式的数据(HTML/PDF/CSV),官方提供的功能更多在传统的搜索应用中表现好于 ES,但实时搜索效率低。
(2)ES自身带有分布式协调管理功能,但仅支持json文件格式,本身更注重于核心功能,高级功能多有第三方插件提供,在处理实时搜索应用时效率明显高于 Solr。
二、安装:
1、ES服务只依赖于JDK,推荐使用JDK1.7+。
2、下载ES安装包,并解压(官方下载地址:https://www.elastic.co/downloads/elasticsearch)
② 运行ES(bin/elasticsearch.bat)
③ 验证(访问:http://localhost:9200/)
3、安装辅助管理工具Kibana5:
(1)下载Kibana5.2.2解压(下载地址:https://www.elastic.co/downloads/kibana)
(2)启动Kibana5 (bin\kibana.bat)
(3)验证(默认访问地址:http://localhost:5601)
(4)代码测试:
#新增
PUT crm/employees/1
{
"name":"测试",
"age":1,
"sex":"男",
"hobby":"篮球"
}
#如果没有指定id 会自动生成一个id
POST crm/employees/
{
"name":"小明",
"age":2,
"sex":"男",
"hobby":"乒乓球"
}
#query
#查询所有
GET _search
GET crm/employees/AWpXd0hyCq6ubXlpA9IX?pretty
#只查询source下面的数据 指定的列
GET crm/employees/AWpXd0hyCq6ubXlpA9IX?_source=name,age,sex
GET crm/employees/AWpXd0hyCq6ubXlpA9IX/_source
GET crm/employees/1/_source
#update
PUT crm/employees/1
{
"name":"小白",
"age":13,
"sex":"女",
"hobby":"听音乐"
}
#会覆盖以前的值
PUT crm/employees/AWpXd0hyCq6ubXlpA9IX
{
"name":"小黑"
}
#只更新局部
POST crm/employees/1/_update
{
"doc":{
"hobby":"恰饭"
}
}
#delete
DELETE crm/employees/1
#批量插入 AWpXiEfhCq6ubXlpA9Ia 4
POST _bulk
{ "delete":{ "_index": "itsource", "_type": "blog", "_id": "4" }}
{ "create":{ "_index": "itsource", "_type": "blog", "_id": "4" }}
{ "title": "春眠不觉晓" }
{ "index": { "_index": "itsource", "_type": "blog" }}
{ "title": "处处闻啼鸟" }
GET itsource/blog/_search
#批量获取方式一
GET _mget
{
"docs":[{
"_index":"itsource",
"_type":"blog",
"_id":"4"
},{
"_index":"itsource",
"_type":"blog",
"_id":"AWpXiEfhCq6ubXlpA9Ia",
"_source":"title"
}]
}
#批量获取方式二
GET itsource/blog/_mget
{
"ids":["123","AWpXiEfhCq6ubXlpA9Ia"]
}
#分页查询
GET _search?size=3&from=2;
GET crm/employees/_search?q=age:1
GET crm/employees/_search?q=age[10 TO 30]
#DSL的查询方式
GET crm/employees/_search
{
"query" : {
"match" : {
"name" : "小白"
}
}
}
GET crm/employees/_search
POST shop/goods/1
{
"id":1,
"name":"iphone",
"price":5000,
"local":"us",
"type":"X系列"
}
POST shop/goods/2
{
"id":2,
"name":"iphone",
"price":6000,
"local":"us",
"type":"S系列"
}
POST shop/goods/3
{
"id":3,
"name":"iphone",
"price":7800,
"local":"us",
"type":"plus系列"
}
POST shop/goods/4
{
"id":4,
"name":"iphone",
"price":7000,
"local":"us",
"type":"P系列"
}
POST shop/goods/5
{
"id":5,
"name":"iphone",
"price":5500,
"local":"us",
"type":"P系列"
}
POST shop/goods/6
{
"id":6,
"name":"iphone",
"price":6600,
"local":"us",
"type":"P系列"
}
POST shop/goods/7
{
"id":7,
"name":"iphone",
"price":7000,
"local":"us",
"type":"P系列"
}
POST shop/goods/8
{
"id":8,
"name":"iphone",
"price":8000,
"local":"cn",
"type":"P系列"
}
#--------------------------------------------------------------
GET shop/goods/_search
{
"query": {
"match": {"name":"iphone"}
},
"from": 1,
"size": 5,
"_source": ["id", "name", "type","price"],
"sort": [{"price": "desc"}]
}
#-------------------------------------
# 类似京东网站 查询关键字为iphone,国家为us的,价格范围6000到8000 价格降序,并# 且取前面2条:
GET shop/goods/_search
{
"query":{
"bool": {
"must": [
{"match": {
"name": "iphone"
}}
],
"filter": [{
"term":{
"local":"us"
}
},{
"range":{
"price":{
"gte":"5000",
"lte":"7000"
}
}
}]
}
},
"from": 1,
"size": 5,
"_source": ["id", "name", "type","price"],
"sort": [{"price": "desc"}]
}
POST _analyze
{
"analyzer":"ik_max_word",
"text":"java编程语言是世界上最好的编程语言"
}
#查询映射
GET shop/goods/_mapping
#删除库
DELETE shop
#创建库
PUT shop
#指定映射类型
POST shop/goods/_mapping
{
"goods": {
"properties": {
"id": {"type": "integer"},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
}
}
}
}
#插入数据
#查询映射类型
GET shop/goods/_mapping
PUT _template/global_template
{
"template":"*",
"settings":{
"number_of_shards":1
},
"mappings":{
"_default_":{
"_all":{
"enabled":false
},
"dynamic_templates":[
{
"string_as_text":{
"match_mapping_type":"string",
"match":"*_text",
"mapping":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word",
"fields":{
"raw":{
"type":"keyword",
"ignore_above":256
}
}
}
}
},
{
"string_as_keyword":{
"match_mapping_type":"string",
"mapping":{
"type":"keyword"
}
}
}
]
}
}
}
#删除库
DELETE shop
#创建库
PUT shop
POST shop/goods/6
{
"id":6,
"name":"iphone",
"price":6600,
"local":"us",
"type_text":"P系列"
}
POST shop/goods/7
{
"id":7,
"name":"iphone",
"price":7000,
"local":"us",
"type_text":"P系列"
}
POST shop/goods/8
{
"id":8,
"name":"iphone",
"price":8000,
"local":"cn",
"type_text":"P系列"
}
GET shop/goods/_mapping
GET itsource/user/1/_source
GET crm/classes/_search
4、IK分词器
(1)下载(IK分词器插件源码地址:https://github.com/medcl/elasticsearch-analysis-ik)
(2)解压放入ES的plugins文件夹下面(主意路径层次,越少越好)
(3)重启ES服务
(4)验证分词(kibana页面)
三、Java API(ES对Java提供一套操作索引库的工具包)
1、引入:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
2、链接ES(要保证ES开启的状态下操作)
//链接ES对象
public static TransportClient getClient() throws Exception {
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
return client;
}
3、创建文档
//创建文档索引
@Test
public void getCreated()throws Exception{
//获取链接ES对象
TransportClient client = getClient();
//创建索引
IndexRequestBuilder index = client.prepareIndex("rpms", "employee", "1");
//设置值
HashMap<String,Object> map = new HashMap();
map.put("id", 2);
map.put("name", "小米");
map.put("age", 20);
map.put("sex", "男");
IndexResponse indexResponse = index.setSource(map).get();
System.out.println(indexResponse);
//获取文档
GetRequestBuilder getRequestBuilder = client.prepareGet("rpms", "employee", "1");
System.out.println(getRequestBuilder);
}
4、更新文档:
//更新文档
@Test
public void updateIndex()throws Exception{
//创建链接
TransportClient client = getClient();
HashMap<String, Object> map = new HashMap();
map.put("id", 2);
map.put("name", "华为");
map.put("age", 18);
UpdateRequestBuilder prepareUpdate = client.prepareUpdate("rpms", "employee", "1");
UpdateResponse updateResponse = prepareUpdate.setDoc(map).get();
System.out.println(updateResponse);
}
//如果没有文档,就需要创建,然后更新操作
@Test
public void getSaveUpdate()throws Exception{
TransportClient client = getClient();
HashMap<String,Object> hashMap = new HashMap();
hashMap.put("id", 2);
hashMap.put("name", "中兴");
hashMap.put("age", 22);
IndexRequest indexRequest = new IndexRequest("rpms", "employee", "1").source(hashMap);
UpdateRequest upsert = new UpdateRequest("rpms", "employee", "1").doc(hashMap).upsert(indexRequest);
UpdateResponse updateResponse = client.update(upsert).get();
System.out.println(updateResponse);
client.close();
}
5、删除
//删除
@Test
public void delete()throws Exception{
TransportClient client = getClient();
DeleteRequestBuilder deleteRequestBuilder = client.prepareDelete("rpms", "employee", "1");
}
6、批量操作
//批量操作
@Test
public void getBulk()throws Exception{
//获取客户端ES对象
TransportClient client = getClient();
//获取批量请求对象
BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
for (int i = 0;i < 20;i++){
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", i);
map.put("name", "苹果"+i);
map.put("age", 10+i);
map.put("class", 1);
bulkRequestBuilder.add(client.prepareIndex("rpms", "employee",i+"").setSource(map));
}
//提交
BulkResponse bulkResponse = bulkRequestBuilder.get();
if (bulkResponse.hasFailures()){
System.out.println("error");
}
//关闭
client.close();
}
7、过滤搜索:
//收索
@Test
public void search()throws Exception{
// 获取客户端的es对象
TransportClient client = getClient();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> must = boolQueryBuilder.must();
must.add(QueryBuilders.termQuery("class","1"));
//过滤
List<QueryBuilder> filter = boolQueryBuilder.filter();
//年龄范围
filter.add(QueryBuilders.rangeQuery("age").gte(10).lte(40));
//分页排序
SearchResponse searchResponse = client.prepareSearch("rpms")
.setFrom(0).setSize(5)
.setQuery(boolQueryBuilder)
.addSort("id", SortOrder.DESC).get();
System.out.println("总条数:"+searchResponse.getHits().getTotalHits());
SearchHit[] hits = searchResponse.getHits().getHits();
// 循环数据结构
for (SearchHit hit : hits) {
System.out.println(hit.getSource());
}
// 关闭资源
client.close();
}