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();


    }