elasticsearch的使用

来源:互联网 发布:微信ipa通知关闭编程 编辑:程序博客网 时间:2024/06/05 03:00

一、安装

1、解压即可  tar -zxvf elasticsearch-1.4.4.tar.gz  

启动 bin/elasticsearch

2、elasticsearch  启动  暂停脚本  elasticsearch-servicewrapper-master.zip

解压   unzip elasticsearch-servicewrapper-master.zip   

在elasticsearch-servicewrapper-master/service  有个elasticsearch脚本       elasticsearch start启动  elasticsearch stop 停止

二、curl 简介

简单认为是可以在命令行下访问url的一个工具

curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用curl可以简单实现常见的get/post请求。

curl 

 -x  指定http请求的方法

HEAD  GET POST  PUT DELETE

-d   指定要传输的数据

如  curl -XPOST 'http://localhost:9200/dept/employee/2' -d '{"empname":"emp2","age":25}'

三、curl创建索引库

curl -XPUT 'http://localhost:9200/index_name/'

PUT/POST都可以

PUT和POST的区别

PUT是幂等方法,POST不是。所以PUT用于更新、POST用于新增比较合适。

PUT,DELETE操作是幂等的。所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。

POST操作不是幂等的,比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。

还有一点需要注意的就是,创建操作可以使用POST,也可以使用PUT,区别在于POST是作用在一个集合资源之上的(/articles),而PUT操作是作用在一个具体资源之上的(/articles/123),再通俗点说,如果URL可以在客户端确定,那么就使用PUT,如果是在服务端确定,那么就使用POST,比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息到底是什么只能由服务端提供,这个时候就必须使用POST。

四、创建索引  PUT/POST

curl -XPOST http://localhost:9200/xiaozhou/employee/1 -d '{

"first_name" : "John",

"last_name" : "Smith",

"age" : 25,

"about" : "I love to go rock climbing",

"interests": [ "sports", "music" ]

}'

ES创建索引时要注意

索引库名称必须要全部小写,不能以下划线开头,也不能包含逗号

如果没有明确指定索引数据的ID,那么es会自动生成一个随机的ID,需要使用POST参数

curl -XPOST http://localhost:9200/xiaozhou/emp/ -d '{"first_name" : "John"}'

如果想要确定我们创建的都是全新的内容

1:使用自增ID

2:在url后面添加参数

curl -XPUT http://localhost:9200/xiaozhou/emp/2?op_type=create -d '{"name":"xiaozhou","age":25}'

curl -XPUT http://localhost:9200/xiaozhou/emp/2/_create -d '{"name":"xiaozhou","age":25}'

如果成功创建了新的文档,Elasticsearch将会返回常见的元数据以及201 Created的HTTP反馈码。而如果存在同名文件,Elasticsearch将会返回一个409 Conflict的HTTP反馈码

五、curl 查询索引 GET

根据员工id查询

curl -XGET http://localhost:9200/xiaozhou/employee/1?pretty

在任意的查询字符串中添加pretty参数,es可以得到易于识别的json结果。

curl后添加-i 参数,这样你就能得到反馈头文件

curl -i  'http://192.168.1.170:9200/xiaozhou/emp/1?pretty'

检索文档中的一部分,如果只需要显示指定字段,

curl -XGET http://localhost:9200/xiaozhou/employee/1?_source=name,age

如果只需要source的数据

curl -XGET http://localhost:9200/xiaozhou/employee/1/_source

 

查询所有

curl -XGET http://localhost:9200/xiaozhou/employee/_search

根据条件进行查询

curl -XGET http://localhost:9200/xiaozhou/employee/_search?q=last_name:Smith

六、查询索引 MGET

使用mget API获取多个文档

curl -XGET http://localhost:9200/_mget?pretty -d '{"docs":[{"_index":"xiaozhou","_type":"emp","_id":1,"_source":"name"},{"_index":"website","_type":"blog","_id":2}]}'

如果你需要的文档在同一个_index或者同一个_type中,你就可以在URL中指定一个默认的/_index或者/_index/_type

curl -XGET http://localhost:9200/xiaozhou/emp/_mget?pretty -d '{"docs":[{"_id":1},{"_type":"blog","_id":2}]}'

如果所有的文档拥有相同的_index 以及 _type,直接在请求中添加ids的数组即可

curl -XGET http://localhost:9200/xiaozhou/emp/_mget?pretty -d '{"ids":["1","2"]}'

注意:如果请求的某一个文档不存在,不会影响其他文档的获取结果。HTTP返回状态码依然是200,这是因为mget这个请求本身已经成功完成。要确定独立的文档是否被成功找到,需要检查found标识。

七、检查文档是否存在 HEAD

如果只想检查一下文档是否存在,你可以使用HEAD来替代GET方法,这样就只会返回HTTP头文件

curl -i -XHEAD http://localhost:9200/xiaozhou/emp/2

八、更新

ES可以使用PUT或者POST对文档进行更新,如果指定ID的文档已经存在,则执行更新操作

注意:执行更新操作的时候

ES首先将旧的文档标记为删除状态

然后添加新的文档

旧的文档不会立即消失,但是你也无法访问

ES会在你继续添加更多数据的时候在后台清理已经标记为删除状态的文档

局部更新,可以添加新字段或者更新已有字段(必须使用POST)

curl -XPOST http://localhost:9200/xiaozhou/emp/1/_update -d '{"doc":{"city":"beijing","car":"BMW"}}'

九、删除

curl -XDELETE http://localhost:9200/xiaozhou/emp/4/

如果文档存在,es会返回200 ok的状态码,found属性值为true,_version属性的值+1

如果文档不存在,es会返回404 Not Found的状态码,found属性值为false,但是_version属性的值依然会+1,这个就是内部管理的一部分,它保证了我们在多个节点间的不同操作的顺序都被正确标记了

注意:删除一个文档也不会立即生效,它只是被标记成已删除。Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理

 

通过查询API删除指定索引库下指定类型下的数据

curl -XDELETE 'http://localhost:9200/xiaozhou/emp/_query?q=user:kimchy'

 

curl -XDELETE 'http://localhost:9200/xiaozhou/emp/_query' -d '{

    "query" : {

        "term" : { "user" : "kimchy" }

    }

}'

 

通过查询API删除指定索引库下多种类型下的数据

curl -XDELETE 'http://localhost:9200/xiaozhou/emp,user/_query?q=user:kimchy'

 

通过查询API删除多个索引库下多种类型下的数据

curl -XDELETE 'http://localhost:9200/xiaozhou,xiaozhou1/emp,user/_query?q=user:kimchy'

或者删除所有索引库中的匹配的数据

curl -XDELETE 'http://localhost:9200/_all/_query?q=tag:wow'

十、批量操作 bulk

与mget类似,bulk API可以帮助我们同时执行多个请求

格式:

action:index/create/update/delete

metadata:_index,_type,_id

request body:_source(删除操作不需要)

  { action: { metadata }}\n

  { request body        }\n

  { action: { metadata }}\n

  { request body        }\n

使用curl -XPOST -d 时注意,不能直接在json字符串中添加\n字符,应该按回车

create 和index的区别

如果数据存在,使用create操作失败,会提示文档已经存在,使用index则可以成功执行。

使用文件的方式

vi requests

curl  -XPOST/PUT localhost:9200/_bulk --data-binary @request;

bulk请求可以在URL中声明/_index 或者/_index/_type

bulk一次最大处理多少数据量

bulk会把将要处理的数据载入内存中,所以数据量是有限制的

最佳的数据量不是一个确定的数值,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载

一般建议是1000-5000个文档,如果你的文档很大,可以适当减少队列,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件中修改这个值http.max_content_length: 100mb

 

vim documents.json{ "index": {"_index": "library", "_type": "book", "_id": "1"}}{ "title": "All Quiet on the Western Front","otitle": "Im Westen nichts Neues","author": "Erich Maria Remarque","year": 1929,"characters": ["Paul Bäumer", "Albert Kropp", "Haie Westhus", "Fredrich Müller", "Stanislaus Katczinsky", "Tjaden"],"tags": ["novel"],"copies": 1, "available": true, "section" : 3}{ "index": {"_index": "library", "_type": "book", "_id": "2"}}{ "title": "Catch-22","author": "Joseph Heller","year": 1961,"characters": ["John Yossarian", "Captain Aardvark", "Chaplain Tappman", "Colonel Cathcart", "Doctor Daneeka"],"tags": ["novel"],"copies": 6, "available" : false, "section" : 1}{ "index": {"_index": "library", "_type": "book", "_id": "3"}}{ "title": "The Complete Sherlock Holmes","author": "Arthur Conan Doyle","year": 1936,"characters": ["Sherlock Holmes","Dr. Watson", "G. Lestrade"],"tags": [],"copies": 0, "available" : false, "section" : 12}{ "index": {"_index": "library", "_type": "book", "_id": "4"}}{ "title": "Crime and Punishment","otitle": "Преступлéние и наказáние","author": "Fyodor Dostoevsky","year": 1886,"characters": ["Raskolnikov", "Sofia Semyonovna Marmeladova"],"tags": [],"copies": 0, "available" : true}
curl -XPOST localhost:9200/_bulk --data-binary @documents.json;

十一、版本控制

普通关系型数据库使用的是(悲观并发控制(PCC))

当我们在读取一个数据前先锁定这一行,然后确保只有读取到数据的这个线程可以修改这一行数据

ES使用的是(乐观并发控制(OCC))

ES不会阻止某一数据的访问,然而,如果基础数据在我们读取和写入的间隔中发生了变化,更新就会失败,这时候就由程序来决定如何处理这个冲突。它可以重新读取新数据来进行更新,又或者将这一情况直接反馈给用户。

ES如何实现版本控制(使用es内部版本号)

1:首先得到需要修改的文档,获取版本(_version)号

curl -XGET http://localhost:9200/xiaozhou/emp/1

2:在执行更新操作的时候把版本号传过去

curl -XPUT http://localhost:9200/xiaozhou/emp/1?version=1 -d '{"name":"xiaozhou","age":25}'(覆盖)

curl -XPOST http://localhost:9200/xiaozhou/emp/1/_update?version=1 -d '{"doc":{"city":"beijing","car":"BMW"}}'(部分更新)

3:如果传递的版本号和待更新的文档的版本号不一致,则会更新失败

 

ES如何实现版本控制(使用外部版本号)

如果你的数据库已经存在了版本号,或者是可以代表版本的时间戳。这时就可以在es的更新url后面添加version_type=external来使用这些号码。

注意:版本号码必须要是大于0小于9223372036854775807(Java中long的最大正值)的整数。

es在处理外部版本号的时候,它不再检查_version是否与请求中指定的数值是否相等,而是检查当前的_version是否比指定的数值小,如果小,则请求成功。

example:

curl -XPUT 'http://localhost:9200/xiaozhou/emp/20?version=10&version_type=external' -d '{"name": "xiaozhou"}'

注意:此处url前后的引号不能省略,否则执行的时候会报错

十二、ES插件介绍

站点插件(以网页形式展现)

BigDesk Plugin (作者 Lukáš Vlček)

简介:监控es状态的插件,推荐!

Elasticsearch Head Plugin (作者 Ben Birch)

简介:很方便对es进行各种操作的客户端。

Paramedic Plugin (作者 Karel Minařík)

简介:es监控插件

SegmentSpy Plugin (作者 Zachary Tong)

简介:查看es索引segment状态的插件

Inquisitor Plugin (作者 Zachary Tong)

简介:这个插件主要用来调试你的查询。

1、Bigdesk plugin

这个主要提供的是节点的实时状态监控,包括jvm的情况,linux的情况,elasticsearch的情况

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

删除bin/plugin --remove bigdesk

http://192.168.1.170:9200/_plugin/bigdesk/

http://192.168.1.170:9200/_cluster/state?pretty

2、Head Plugin

这个主要提供的是健康状态查询

安装bin/plugin -install mobz/elasticsearch-head

http://192.168.1.170:9200/_plugin/head/

http://192.168.1.170:9200/_cluster/health?pretty

十三、JAVA客户端操作ES

package cn.xiaozhou.elasticsearch_08;

import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Before;
import org.junit.Test;

import com.fasterxml.jackson.databind.ObjectMapper;

//通过反射创建客户端工具类

public class EsUtil {

  // 设置client.transport.sniff为true来使客户端去嗅探整个集群的状态,把集群中其它机器的ip地址加到客户端中,

  static Settings settings = ImmutableSettings.settingsBuilder()

  .put("cluster.name", "elasticsearch")

  .put("client.transport.sniff", true).build();

  // 创建私有对象

  private static TransportClient client;

  static {

  try {

  Class<?> clazz = Class.forName(TransportClient.class.getName());

  Constructor<?> constructor = clazz

  .getDeclaredConstructor(Settings.class);

  constructor.setAccessible(true);

  client = (TransportClient) constructor.newInstance(settings);

  client.addTransportAddress(new InetSocketTransportAddress(

  "192.168.1.170", 9300));

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  public static synchronized TransportClient getTransportClient() {

  return client;

  }

}

public class TestEs {
    TransportClient client;
    @Before
    public void test1() throws Exception {
        //获取一个Transport客户端对象
        client = new TransportClient();
        //指定连接的es节点ip和端口,端口在这默认使用9300
        client.addTransportAddress(new InetSocketTransportAddress("192.168.1.170", 9300));
        client.addTransportAddress(new InetSocketTransportAddress("192.168.1.171", 9300));
        //获取transport客户端已经连接上的节点信息
        /*ImmutableList<DiscoveryNode> connectedNodes = client.connectedNodes();
        for (DiscoveryNode discoveryNode : connectedNodes) {
            System.out.println(discoveryNode.getHostAddress());
        }*/
    }
    
    @Test
    public void test2() throws Exception {
        //设置一些配置属性
        Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", "elasticsearch").build();
        //获取一个Transport客户端对象
        TransportClient transportClient = new TransportClient(settings);
        //指定连接的es节点ip和端口,端口在这默认使用9300
        transportClient.addTransportAddress(new InetSocketTransportAddress("192.168.1.170", 9300));
        transportClient.addTransportAddress(new InetSocketTransportAddress("192.168.1.171", 9300));
        //获取transport客户端已经连接上的节点信息
        ImmutableList<DiscoveryNode> connectedNodes = transportClient.connectedNodes();
        for (DiscoveryNode discoveryNode : connectedNodes) {
            System.out.println(discoveryNode.getHostAddress());
        }
    }
    
    /**
     * 建议使用这种方式
     * @throws Exception
     */
    @Test
    public void test3() throws Exception {
        //设置一些配置属性(可以自动嗅探集群中的其它节点)
        Settings settings = ImmutableSettings.settingsBuilder().put("client.transport.sniff", true).build();
        //获取一个Transport客户端对象
        TransportClient transportClient = new TransportClient(settings);
        //指定连接的es节点ip和端口,端口在这默认使用9300
        transportClient.addTransportAddress(new InetSocketTransportAddress("192.168.1.170", 9300));
        //获取transport客户端已经连接上的节点信息
        ImmutableList<DiscoveryNode> connectedNodes = transportClient.connectedNodes();
        for (DiscoveryNode discoveryNode : connectedNodes) {
            System.out.println(discoveryNode.getHostAddress());
        }
        
    }
    String index = "xiaozhou";
    String type = "emp";
    
    /**
     * 创建索引--json
     * @throws Exception
     */
    @Test
    public void test4() throws Exception {
        String jsonstr = "{\"name\":\"ls\",\"age\":10}";
        IndexResponse response = client.prepareIndex(index, type, "2").setSource(jsonstr).execute().actionGet();
        System.out.println(response.getId());
        
    }
    
    /**
     * 创建索引--map
     * @throws Exception
     */
    @Test
    public void test5() throws Exception {
        HashMap<String, Object> hashMap = new HashMap<String, Object>();
        hashMap.put("name", "ww");
        hashMap.put("age", 18);
        IndexResponse response = client.prepareIndex(index, type, "3").setSource(hashMap).execute().actionGet();
        System.out.println(response.getId());
    }
    
    /**
     * 创建索引--bean
     * @throws Exception
     */
    @Test
    public void test6() throws Exception {
        Person person = new Person();
        person.setName("aa");
        person.setAge(10);
        
        ObjectMapper objectMapper = new ObjectMapper();
        IndexResponse response = client.prepareIndex(index, type, "4").setSource(objectMapper.writeValueAsString(person)).execute().actionGet();
        System.out.println(response.getId());
    }
    
    /**
     * 创建索引--es 工具类
     * @throws Exception
     */
    @Test
    public void test7() throws Exception {
        XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
            .field("name", "ww").field("age",20)
            .endObject();
        IndexResponse response = client.prepareIndex(index, type, "4").setSource(builder).execute().actionGet();
        System.out.println(response.getId());
    }
    
    
    /**
     * 查询-get
     * @throws Exception
     */
    @Test
    public void test8() throws Exception {
        GetResponse response = client.prepareGet(index, type, "1").execute().actionGet();
        System.out.println(response.getSourceAsString());
    }
    
    /**
     * 更新 --1
     * @throws Exception
     */
    @Test
    public void test9() throws Exception {
        UpdateRequest request = new UpdateRequest(index, type, "1");
        request.doc(XContentFactory.jsonBuilder().startObject().field("age", 18).endObject());
        UpdateResponse response = client.update(request ).get();
        System.out.println(response.getVersion());
    }
    
    /**
     * 更新--2
     * @throws Exception
     */
    @Test
    public void test10() throws Exception {
        XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("name", "xiaozhou").endObject();
        
        UpdateResponse response = client.prepareUpdate(index, type, "1").setDoc(builder).get();
        System.out.println(response.getVersion());
    }
    
    
    /**
     * 更新或者插入
     * @throws Exception
     */
    @Test
    public void test11() throws Exception {
        
        UpdateRequest request = new UpdateRequest(index, type, "11");
        request.doc(XContentFactory.jsonBuilder().startObject().field("name", "cxry123").endObject());
        request.upsert(XContentFactory.jsonBuilder().startObject().field("name", "aaaaa").field("age", 23).endObject());
        UpdateResponse response = client.update(request ).get();
        System.out.println(response.getVersion());
    }
    
    
    /**
     * 删除
     * @throws Exception
     */
    @Test
    public void test12() throws Exception {
        DeleteRequest request = new DeleteRequest();
        request.index(index);
        request.type(type);
        request.id("11");
        DeleteResponse response = client.delete(request ).get();
        System.out.println(response.getVersion());
        
    }
    /**
     * 查询指定索引库中数据的总数
     * 相当于数据库中的select count(*)
     * @throws Exception
     */
    @Test
    public void test13() throws Exception {
        long count = client.prepareCount(index).execute().get().getCount();
        System.out.println(count);
    }
    
    
    /**
     * 批量操作bulk
     * 非常适合做一些数据批量处理
     * @throws Exception
     */
    @Test
    public void test14() throws Exception {
        BulkRequestBuilder prepareBulk = client.prepareBulk();
        //创建索引
        IndexRequest indexrequest = new IndexRequest(index, type, "12");
        indexrequest.source(XContentFactory.jsonBuilder().startObject().field("name", "test12").field("age", 12).endObject());
        //删除索引
        DeleteRequest deleteRequest = new DeleteRequest(index, type, "3");
        
        prepareBulk.add(indexrequest);
        prepareBulk.add(deleteRequest);
        
        BulkResponse response = prepareBulk.execute().actionGet();
        if(response.hasFailures()){
            System.out.println("出现执行失败的语句");
            BulkItemResponse[] items = response.getItems();
            for (BulkItemResponse bulkItemResponse : items) {
                System.out.println(bulkItemResponse.getFailureMessage());
            }
        }else{
            System.out.println("全部执行成功");
        }
    }
    
    /**
     * 查询-search
     * @throws Exception
     */
    @Test
    public void test15() throws Exception {
        SearchResponse response = client
                //指定索引库
                .prepareSearch(index)
                //指定类型
                .setTypes(type)
                //指定查询类型
                .setSearchType(SearchType.QUERY_THEN_FETCH)
                //指定要查询的关键字
                .setQuery(QueryBuilders.matchQuery("name", "中国人"))
                //相当于实现分页
                .setFrom(0)
                .setSize(10)
                //执行查询
                .execute().actionGet();
        //可以获取查询的所有内容
        SearchHits hits = response.getHits();
        //获取查询的数据总数
        long totalHits = hits.getTotalHits();
        System.out.println("总数:"+totalHits);
        SearchHit[] hits2 = hits.getHits();
        for (SearchHit searchHit : hits2) {
            System.out.println(searchHit.getSourceAsString());
        }
        
    }
    /**
     * 排序
     * @throws Exception
     */
    @Test
    public void test16() throws Exception {
        SearchResponse response = client
                //指定索引库
                .prepareSearch(index)
                //指定类型
                .setTypes(type)
                //指定查询类型
                .setSearchType(SearchType.QUERY_THEN_FETCH)
                //添加排序字段并指定排序类型
                .addSort("age", SortOrder.DESC)
                //相当于实现分页
                .setFrom(0)
                .setSize(10)
                //执行查询
                .execute().actionGet();
        //可以获取查询的所有内容
        SearchHits hits = response.getHits();
        //获取查询的数据总数
        long totalHits = hits.getTotalHits();
        System.out.println("总数:"+totalHits);
        SearchHit[] hits2 = hits.getHits();
        for (SearchHit searchHit : hits2) {
            System.out.println(searchHit.getSourceAsString());
        }
        
    }
    
    
    /**
     * 过滤
     * lt:小于
     * lte:小于等于
     * gt:大于
     * gte:大于等于
     * @throws Exception
     */
    @Test
    public void test17() throws Exception {
        SearchResponse response = client
                //指定索引库
                .prepareSearch(index)
                //指定类型
                .setTypes(type)
                //指定查询类型
                .setSearchType(SearchType.QUERY_THEN_FETCH)
                .setPostFilter(FilterBuilders.rangeFilter("age").gte(20).lte(25))
                //相当于实现分页
                .setFrom(0)
                .setSize(10)
                //执行查询
                .execute().actionGet();
        //可以获取查询的所有内容
        SearchHits hits = response.getHits();
        //获取查询的数据总数
        long totalHits = hits.getTotalHits();
        System.out.println("总数:"+totalHits);
        SearchHit[] hits2 = hits.getHits();
        for (SearchHit searchHit : hits2) {
            System.out.println(searchHit.getSourceAsString());
        }
        
    }
    
    
    /**
     * 高亮
     * @throws Exception
     */
    @Test
    public void test18() throws Exception {
        SearchResponse response = client
                //指定索引库
                .prepareSearch(index)
                //指定类型
                .setTypes(type)
                //指定查询类型
                .setSearchType(SearchType.QUERY_THEN_FETCH)
                //指定要查询的关键字
                .setQuery(QueryBuilders.matchQuery("name", "中国人"))
                .addHighlightedField("name")
                .setHighlighterPreTags("<font color='red'>")
                .setHighlighterPostTags("</font>")
                //相当于实现分页
                .setFrom(0)
                .setSize(10)
                //执行查询
                .execute().actionGet();
        //可以获取查询的所有内容
        SearchHits hits = response.getHits();
        //获取查询的数据总数
        long totalHits = hits.getTotalHits();
        System.out.println("总数:"+totalHits);
        SearchHit[] hits2 = hits.getHits();
        for (SearchHit searchHit : hits2) {
            //获取所有高亮内容
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            //根据设置的高亮字段获取高亮内容
            HighlightField highlightField = highlightFields.get("name");
            Text[] fragments = highlightField.getFragments();
            for (Text text : fragments) {
                System.out.println(text);
            }
            System.out.println(searchHit.getSourceAsString());
        }
    }
    

/**
     * 根据查询条件进行删除数据
     * @throws Exception
     */
    @Test
    public void test19() throws Exception {
        DeleteByQueryResponse response = client.prepareDeleteByQuery(index)
        .setQuery(QueryBuilders.matchAllQuery())
        .execute().actionGet();
    }
    
    /**
     * 根据姓名分组,统计相同姓名有多少条数据
     * @throws Exception
     */
    @Test
    public void test20() throws Exception {
        SearchResponse response = client.prepareSearch(index).setTypes(type)
            .addAggregation(AggregationBuilders.terms("group").field("name"))
            //默认返回分组之后的前十条数据,设置为0之后会返回所有的数据
            .setSize(0)
            .execute().actionGet();
        Terms terms = response.getAggregations().get("group");
        List<Bucket> buckets = terms.getBuckets();
        for (Bucket bucket : buckets) {
            System.out.println(bucket.getKey()+"------"+bucket.getDocCount());
        }
    }
    
    
    /**
     * (业务场景不合理)
     * 根据姓名分组,统计相同姓名的年龄的和
     * @throws Exception
     */
    @Test
    public void test21() throws Exception {
        SearchResponse response = client.prepareSearch(index).setTypes(type)
            .addAggregation(AggregationBuilders.terms("group").field("name")
                    .subAggregation(AggregationBuilders.sum("sum").field("age")))
            //默认返回分组之后的前十条数据,设置为0之后会返回所有的数据
            .setSize(0)
            .execute().actionGet();
        Terms terms = response.getAggregations().get("group");
        List<Bucket> buckets = terms.getBuckets();
        for (Bucket bucket : buckets) {
            Sum sum  = bucket.getAggregations().get("sum");
            System.out.println(bucket.getKey()+"------"+sum.getValue());
        }
    }

//用代码的方式改变副本和分布的数量
    @Test
    public void test23() throws Exception {
         Map<String, Object> settings = new HashMap<String, Object>();  
            settings.put("number_of_shards", 4);//分片数量  
            settings.put("number_of_replicas", 0);//副本数量  
            settings.put("refresh_interval", "10s");//刷新时间  
        AdminClient admin = client.admin();
        CreateIndexResponse actionGet = admin.indices().prepareCreate("aa").setSettings(settings).execute().actionGet();
        System.out.println(actionGet.getContext());
    }

 

@Test
    public void test24() throws Exception {

//指定从哪个分片查找数据   有以下方式

//_local  先从本地分片查询数据

//*_primary:指查询只在主分片中查询

//*_primary_first:指查询会先在主分片中查询,如果主分片找不到(挂了),就会在副本中查询。

//*_only_node:指在指定id的节点里面进行查询,如果该节点只有要dx查询索引的部分分片,就只在这部分分片中查找,所以查询结果可能不完整。如_only_node:123在节点id为123的节点中查询。

//*_prefer_node:nodeid 优先在指定的节点上执行查询

//*_shards:0 ,1,2,3,4:查询指定分片的数据
        SearchResponse response = client.prepareSearch(index).setTypes(type).setSearchType(SearchType.QUERY_THEN_FETCH).setPreference("_local")
                .setPostFilter(FilterBuilders.rangeFilter("age").gt(80)).execute().actionGet();
                
                SearchHits hits = response.getHits();
                System.out.println("总共有多少条数据"+hits.getTotalHits());
                SearchHit[] hits2 = hits.getHits();
                for (SearchHit searchHit : hits2) {
                    
                    System.out.println(searchHit.getSourceAsString());
                }
    }

}
 

十四、ES基础中文分词器IK

elasticsearch官方提供的分词插件,对中文分词效果不是很好

curl 'http://localhost:9200/xiaozhou/_analyze?pretty=true' -d '{"text":"大家好"}'

集成IK分词工具

1:下载es的IK插件https://github.com/medcl/elasticsearch-analysis-ik

2:使用maven进行编译下载的源码  命令 mvn clean package -DskipTests\

3:把编译后的target/releases下的elasticsearch-analysis-ik-1.2.9.zip文件拷贝到ES_HOME/plugins/analysis-ik目录下面,然后解压

4:把下载的ik插件中的conf/ik目录拷贝到ES_HOME/config下

5:修改ES_HOME/config/elasticsearch.yml文件,添加index.analysis.analyzer.default.type: ik(把IK设置为默认分词器,这一步是可选的)

6:重启es服务

7:测试分词效果: curl 'http://localhost:9200/xiaozhou/_analyze?analyzer=ik&pretty=true' -d '{"text":"大家好"}'