• 了解 elasticsearch 的基本概念及搜索的整体流程
  • 理解 elasticsearch 涉及的关键性名词
  • elasticsearch 环境搭建

 

ElasticSearch 是一个基于 Lucene 的搜索服务器。它是一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 是用 Java 开发的。

目前 Elasticsearch 与阿里云携手合作在阿里云上提供的 Elasticsearch 和 Kibana 托管云服务,包含 X-Pack 全部功能。目前应用 elasticsearch 构建搜索系统的公司有:Github 使用 Elasticsearch 搜索 TB 级别的数据、Sony(Sony 公司使用 elasticsearch 作为信息搜索引擎)国内有赶集网、京东等

 

 

 

cluster(集群)

代表一个集群,集群中有多个节点,其中有一个为主节点,默认这个主节点是可以通过选举产生的,配置方式可指定哪些节点主节点,哪些节点数据节点,主从节点是对于集群内部来说的。es 的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看 es 集群,在逻辑上是个整体,你与任何一个节点的通信和与整个 es 集群通信是等价的。

shards(分片)

代表索引分片,es 可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索,可提高搜索性能,当然也不是越大越好,还是要看你要存储的数据量,如果数据量大,可把分片设置大点,数据量小,可把分片设置小点,默认是 5 个分片,分片的数量只能在索引创建前指定,并且索引创建后不能更改。

replicas(副本)

代表索引副本,es 可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高 es 的查询效率,es 会自动对搜索请求进行负载均衡。默认是 1 个副本。

gateway

代表 es 索引快照的存储方式,es 默认是先把索引存放到内存中,当内存满了时再持久化到本地硬盘,默认是 1 g,官方建议一个节点最大不超过 32G,超过 32G 性能反而会下降。gateway 对索引快照进行存储,当这个 es 集群关闭再重新启动时就会从 gateway 中读取索引备份数据。

discovery.zen

代表 es 的自动发现节点机制,es 是一个基于 p2p 的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。早期的版本不需要任何配置,只要在一个网段,启动后就会组成集群,非常方便,但是同时也带来了问题,某台机器的测试数据和另一台机器的数据会互相同步。

Transport

代表 es 内部节点或集群与客户端的交互方式,默认内部是使用 tcp 协议进行交互,同时它支持 http 协议(json 格式)、thrift、servlet、memcached、zeroMQ 等的传输协议(通过插件方式集成)java 客户端的方式是以 tcp 协议在 9300 端口上进行通信 http 客户端的方式是以 http 协议在 9200 端口上进行通信。

 

 

 elasticsearch 安装

 

配置java环境变量

export ES_HOME=/home/lizejun/Desktop/elk/elasticsearch-2.3.4
export JAVA_HOME=/usr/local/jdk1.8.0_231/
export PATH=.:$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

 

source /etc/profile 

 

 

sudo wget https://labfile.oss.aliyuncs.com/courses/1014/elasticsearch-2.3.4.zip
unzip elasticsearch-2.3.4.zip
cd elasticsearch-2.3.4/
mkdir logs
mkdir data
cd bin/

sudo wget https://labfile.oss.aliyuncs.com/courses/1014/elasticsearch-servicewrapper-master.zip

github地址: https://github.com/elastic/elasticsearch-servicewrapper

unzip elasticsearch-servicewrapper-master.zip
mv elasticsearch-servicewrapper-master/service/ .

 

修改配置 elasticsearch-2.3.4/bin/service/elasticsearch.conf 和 elasticsearch-2.3.4/config/elasticsearch.yml

 

vim service/elasticsearch.conf

 

wrapper.java.classpath.1=%ES_HOME%/bin/service/lib/wrapper.jar
#wrapper.java.classpath.2=%ES_HOME%/lib/elasticsearch*.jar
wrapper.java.classpath.2=%ES_HOME%/lib/*.jar
wrapper.java.classpath.3=%ES_HOME%/lib/sigar/*.jar

 

# Initial Java Heap Size (in MB)
wrapper.java.initmemory=%ES_HEAP_SIZE%
wrapper.java.additional.10=-Des.insecure.allow.root=true

启动参数

# Application parameters. Add parameters as needed starting from 1
#wrapper.app.parameter.1=org.elasticsearch.bootstrap.ElasticsearchF
wrapper.app.parameter.1=org.elasticsearch.bootstrap.Elasticsearch
wrapper.app.parameter.2=start

 

# Initial Java Heap Size (in MB)
wrapper.java.initmemory=%ES_HEAP_SIZE%  默认是1024 ,修改:set.default.ES_HEAP_SIZE=1024


wrapper.java.additional.10=-Des.insecure.allow.root=true

 

vim  elasticsearch-2.3.4/config/elasticsearch.yml

network.host: 127.0.0.1
security.manager.enabled: false

 

启动服务

cd /home/lizejun/Desktop/elk/elasticsearch-2.3.4/bin/service

sudo ./elasticsearch install
./elasticsearch start
 ./elasticsearch status

Elasticsearch is running: PID:37838, Wrapper:STARTED, Java:STARTED

  Unsupported major.minor version 51.0

Version和JDK版本的对应关系:

52.0 -> 8.0
51.0 -> 7.0
50.0 -> 1.6
49.0 -> 1.5

jdk版本比较低

head插件安装和ik分词安装

1.elasticsearch-head 是一个界面化的集群操作和管理工具,可以对集群进行傻瓜式操作。

  • 显示集群的拓扑,并且能够执行索引和节点级别操作

  • 搜索接口能够查询集群中原始 json 或表格格式的检索数据

  • 能够快速访问并显示集群的状态

  • 有一个输入窗口,允许任意调用 RESTful API

    2.Elasticsearch 提供默认提供的分词器 standard (标准分词器)和 chinese (中文分词),会把每个汉字分开,而不是我们想要的根据关键词来分词,比如我们更希望 “中国人”,“中国”,“我”这样的分词,因此需要安装中文分词插件 IK 来实现此功能。elasticsearch-analysis-ik 是一款中文的分词插件,支持自定义词库。

 

 

 

/home/lizejun/Desktop/elk/elasticsearch-2.3.4/

mkdir plugins

sudo wget https://labfile.oss.aliyuncs.com/courses/1014/elasticsearch-head-master.zip

unzip elasticsearch-head-master.zip
mv elasticsearch-head-master head

/home/lizejun/Desktop/elk/elasticsearch-2.3.4/bin/service

 

./elasticsearch stop

./elasticsearch start 

http://localhost:9200/_plugin/head/

 

 

 

 

ik

cd plugins/
 mkdir elasticsearch-analysis-ik-1.8.1
sudo wget https://labfile.oss.aliyuncs.com/courses/1014/elasticsearch-analysis-ik-1.8.1.zip
unzip elasticsearch-analysis-ik-1.8.1.zip -d elasticsearch-analysis-ik-1.8.1
ls elasticsearch-analysis-ik-1.8.1
mv elasticsearch-analysis-ik-1.8.1.zip ~/Desktop/elk/
cd elasticsearch-analysis-ik-1.8.1/
 vim plugin-descriptor.properties

 

cd  /home/lizejun/Desktop/elk/elasticsearch-2.3.4/bin/service

 ./elasticsearch stop
 ./elasticsearch status
./elasticsearch start
 cat ../../logs/elasticsearch.log|grep "ik-analyzer"

izejun@ubuntu:~/Desktop/elk/elasticsearch-2.3.4/bin/service$ cat ../../logs/elasticsearch.log|grep "ik-analyzer"
[2021-02-09 08:57:05,019][INFO ][ik-analyzer ] [Dict Loading] ik/custom/mydict.dic
[2021-02-09 08:57:05,020][INFO ][ik-analyzer ] [Dict Loading] ik/custom/single_word_low_freq.dic
[2021-02-09 08:57:05,022][INFO ][ik-analyzer ] [Dict Loading] ik/custom/ext_stopword.dic

 

ps -ef|grep elast|grep -v grep |wc -l

 elasticsearch 外网访问

修改:elasticsearch.yml文件
添加

network.host: 0.0.0.0

 

 

elasticserch索引创建

 

  • 了解 index 的基本概念
  • 通过调用 api 的方式 创建 index
  • 通过 head 查看创建的索引
  • 通过调用 api 的方式删除 index

 

一个 index 是一个索引的集合,比如淘宝的商品信息和里面资讯信息肯定是两个不同的索引,Index 可以理解为逻辑数据库。

创建maven项目:syl_es  包名:com.syl.es 

<mirror>
    <id>aliyunmaven</id>
    <mirrorOf>*</mirrorOf>
    <name>阿里云公共仓库</name>
    <url>https://maven.aliyun.com/repository/public</url>
</mirror>


pom依赖
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.3.4</version>
</dependency>

创建索引代码
package com.syl.es;

import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;

import java.net.InetAddress;

public class CreateIndex {

    public static void main(String[] args) {
//        createIndex("user");
        for (int i = 0 ; i<10;i++){
            createIndex("test"+i);
        }


    }

    private static void createIndex(String indicas) {

        String server = "192.168.154.129";
        Integer port = 9300;

        Client client = null;
        try {
            // 初始化连接
            Settings settings = Settings.builder().build();
            client = TransportClient.builder().settings(settings).build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(server),port));

            // 创建索引
            client.admin().indices().prepareCreate(indicas).execute().actionGet();
            // 关闭连接
            client.close();
        }catch (Exception e ){
            e.printStackTrace();
        }
    }
}

  

 

 默认5个分片

 

删除索引

 

 

/**
     * 删除索引
     * @param indices
     */
    public  static  void deleteClusterName(String indices){
        String server = "192.168.154.129";
        Integer port = 9300;

        Client client = null;
        try {
            // 初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(server),port));

            // 删除索引
            client.admin().indices().prepareDelete(indices).execute().actionGet();
            // 关闭连接
            client.close();
        }catch (Exception e ){
            e.printStackTrace();
        }
    }

  

  elasticsearch 的 mapping

  • 了解 mapping 的基本概念
  • 理解创建 mapping 的字段几种定义方式
  • 通过 java 创建 elasticsearch 的 mapping

 

 Mapping 对应数据库里的表定义,我们都知道数据库表有各种字段每种字段使用场景是不一样,mapping 中字段也类似数据库字段,定义形式不同搜索场景也不同 ,mapping 还有一些其他的含义,mapping 不仅告诉 ES 一个 field 中是什么类型的值,它还告诉 ES 如何索引数据以及数据是否能被搜索到,Mapping 是对于 index 上每种 type 的定义

 

 

mapping 字段定义的使用,我们下面针对常用的进行说明

  • index: "analyzed" //分词,不分词是:not_analyzed ,设置成 no,字段将不会被索引
  • analyzer: "ik" //指定分词器
  • search_analyzer: "ik" //设置搜索时的分词器,默认跟 ananlyzer 是一致的

 

package com.syl.es;

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

import java.net.InetAddress;

public class CreateMapping {


    public static void main(String[] args) {
        createMapping("user","userinfo");
    }

    private static void createMapping(String indices, String mappingType) {

        String server = "192.168.154.129";
        Integer port = 9300;

        Client client = null;

        try {
            // 初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(server),port));
            new XContentFactory();
            XContentBuilder builder = XContentFactory.jsonBuilder()
                    .startObject()
                    .startObject(mappingType)
                    .startObject("properties")
                    .startObject("name").field("type","string")
                    .field("index","no").endObject()
            //.field("searchAnalyzer","ik").endObject()
.startObject("nickname").field("type","string") .field("index","not_analyzed").endObject() .startObject("nativeplace").field("type","string") .field("index","no").endObject() .startObject("birthday").field("type","date") .field("format","yyyy-MM-dd") .field("index","not_analyzed").endObject() .endObject() .endObject() .endObject(); System.out.println(builder.toString()); PutMappingRequest mapping = Requests.putMappingRequest(indices).type(mappingType).source(builder); client.admin().indices().putMapping(mapping).actionGet(); client.close(); }catch (Exception e){ e.printStackTrace(); } } } // [user] IndexNotFoundException[no such index] /** * 问题分析 * 这是因为Elasticsearch默认安装时禁用了自动创建索引的功能。在action.auto_create_index选项中没有配置test_*样式的索引自动创建条目。 * * 解决方法 * 关闭已经运行的Elasticsearch; * 在$ES_HOME\config中打开elasticsearch.xml配置文件 * 在action.auto_create_index选项后增加“,test_”的内容,以匹配索引的自动创建;或者直接将action.auto_create_index的值修改为“”。 * 重新启动elasticsearch。 * * 如何修改自动创建索引auto_create_index参数? * 执行以下命令修改。 * PUT /_cluster/settings * { * "persistent" : { * "action": { * "auto_create_index": "false" * } * } * } * 注意 auto_create_index参数的默认值为false,表示不允许自动创建索引。一般建议您不要调整该值,会引起索引太多、索引Mapping和Setting不符合预期等问题。 * *手动修改/etc/elasticsearch/elasticsearch.yml文件 * * #添加权限(默认为true) * action.auto_create_index:true * 或者在kibana中执行命令 * * PUT _cluster/settings * { * "persistent": { * "action.auto_create_index": "true" * } * }

以 Java Application 的方式,运行CreateMapping.java文件 (在运行 CreateMapping.java 之前,需要创建好索引) */

  

 

{
"state": "open",
"settings": {
"index": {
"creation_date": "1612976023621",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "nqcY1Ir9REidAxdOLt8oXA",
"version": {
"created": "2030499"
}
}
},
"mappings": {
"userinfo": {
"properties": {
"birthday": {
"format": "yyyy-MM-dd",
"type": "date"
},
"name": {
"index": "no",
"type": "string"
},
"nickname": {
"index": "not_analyzed",
"type": "string"
},
"nativeplace": {
"index": "no",
"type": "string"
}
}
}
},
"aliases": [ ]
}

  


ela添加数据

  • 了解创建数据的流程
  • 通过 java 创建 elasticsearch 单条数据
  • 通过 java 创建 elasticsearch 多条数据

通过调用 Es java api 后与 Es 服务交互,Es 将数据散布到多个物理 Lucene 索引上,这些 Lucene 索引称为分片,es 默认是 5 个分片,如果是集群状态分片将会分配到多个节点上

 

package com.syl.es;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

public class AddData {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //调用添加数据方法
        add();
    }

    /**
     * 添加索引数据
     */
    public static void add(){
        //索引服务的地址
        String elasticServer= "192.168.154.129";
        //索引服务的端口
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            //初始化连接
            Settings settings = Settings.settingsBuilder()
                    .build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(elasticServer), elasticServerPort));
            BulkRequestBuilder bulkRequest = client.prepareBulk();
            //设置字段的值
            XContentBuilder docBuilder = XContentFactory.jsonBuilder().startObject();
            docBuilder.field("name", "张中国");
            docBuilder.field("nickname", "张中");
            docBuilder.field("nativeplace", "上海静安寺");
            docBuilder.field("address", "上海静安寺1街坊10栋");
            docBuilder.field("birthdate", "1980-02-14");
            //添加索引数据并且设置id为1
            System.out.println(docBuilder.toString());
            bulkRequest.add(client.prepareIndex("user", "userInfo", "1")
                    .setSource(docBuilder));
            BulkResponse bulkResponse = bulkRequest.execute().actionGet();
            System.out.println(bulkResponse.hasFailures());
            //判断添加是否成功
            if (bulkResponse.hasFailures()) {
                System.out.println("error!!!");
            }
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("do end!!");
    }
}

  

 

 

 

{
"_index": "user",
"_type": "userInfo",
"_id": "1",
"_version": 1,
"_score": 1,
"_source": {
"name": "张中国",
"nickname": "张中",
"nativeplace": "上海静安寺",
"address": "上海静安寺1街坊10栋",
"birthdate": "1980-02-14"
}
}

  

批量添加数据

 

 /**
     * 批量添加索引数据
     */
    public static void batchAdd (){
        //初始化数据
        List dataList = new ArrayList();
        Map dataMap1=new HashMap();
        dataMap1.put("name","张中国1");
        dataMap1.put("nickname", "张中1");
        dataMap1.put("nativeplace", "上海静安寺1");
        dataMap1.put("address", "上海静安寺1街坊10栋1");
        dataMap1.put("birthdate", "1980-02-15");

        Map dataMap2=new HashMap();
        dataMap2.put("name","张中国2");
        dataMap2.put("nickname", "张中2");
        dataMap2.put("nativeplace", "上海静安寺2");
        dataMap2.put("address", "上海静安寺1街坊10栋2");
        dataMap2.put("birthdate", "1980-02-16");
        dataList.add(dataMap1);
        dataList.add(dataMap2);
        //索引服务的地址
        String elasticServer= "192.168.154.129";
        //索引服务的端口
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            //初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(elasticServer), elasticServerPort));
            BulkRequestBuilder bulkRequest = client.prepareBulk();
            int y=dataList.size();
            //添加数据
            for(int i=0;i<y;i++){
                Map<String, Object> m = (Map)dataList.get(i);
                bulkRequest.add(client.prepareIndex("user", "userInfo", i+5+"")
                        .setSource(m));
                if (i % 10000 == 0) {
                    bulkRequest.execute().actionGet();
                }
            }
            bulkRequest.execute().actionGet();
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("do end!!");
    }

  

 elasticsearch查询数据

  • 了解搜索数据的几种情况
  • 通过 java 查询全部数据
  • 通过 java 查询部分数据
  • 通过调用 api 了解模糊搜索

 

 

不了解 elasticsearch 的人都以为 Es 只能进行模糊搜索,其实不仅能进行模糊搜索还能进行全匹配搜索。在集群模式 elasticsearch 的搜索把多个节点的数据汇集到一个节点最终显示给调用端,索引数据必须指定_index(database)及 index 下面的 type(table)。

 

查询所有

package com.syl.es;

import java.net.InetAddress;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;

public class QueryData1 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //调用搜索全部数据方法
        searchAll();
    }
    /**
     * 搜索全部数据
     */
    public static void searchAll(){
        //索引服务的地址
        String elasticServer= "192.168.154.129";
        //索引服务的端口
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            //初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(
                            InetAddress.getByName(elasticServer), elasticServerPort));
            //搜索全部数据
            QueryBuilder  bqb=QueryBuilders.matchAllQuery();
            System.out.println(bqb.toString()+"====================");
            SearchResponse response = client.prepareSearch("user").setTypes("userInfo") //set index set type
                    .setQuery(bqb.toString())
                    .execute()
                    .actionGet();
            SearchHits hits = response.getHits();
            System.out.println(hits.getTotalHits() +" "+ hits.getHits().length);
            for (int i = 0; i < hits.getHits().length; i++) {
                System.out.println("===searchAll()====="+hits.getAt(i).getId()+"-------"
                        + "------"+hits.getAt(i).getSource());
            }
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  

 查询指定size的数据

   /**
     * 搜索指定数量数据
     */
    public static void searchSize(){
        //索引服务的地址
        String elasticServer= "192.168.154.129";
        //索引服务的端口
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            //初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(
                            InetAddress.getByName(elasticServer), elasticServerPort));
            //搜索数据
            QueryBuilder  bqb=QueryBuilders.matchAllQuery();
            SearchResponse response = client.prepareSearch("user").setTypes("userInfo")
                    .setQuery(bqb.toString())
                    .setFrom(0).setSize(2)//设置条数
                    .execute()
                    .actionGet();
            SearchHits hits = response.getHits();
            System.out.println(hits.getTotalHits() +" "+ hits.getHits().length);
            //打印搜索结果
            for (int i = 0; i < hits.getHits().length; i++) {
                System.out.println("====searchSize()==="+hits.getAt(i).getId()+"------"
                        + "-------"+hits.getAt(i).getSource());
            }
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

  模糊查询

    /**
     * 模糊搜索索引数据
     */
    public static void searchMatchQuery(){
        //索引服务的地址
        String elasticServer= "127.0.0.1";
        //索引服务的端口
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            //初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(
                            InetAddress.getByName(elasticServer), elasticServerPort));
            //设置查询条件
            BoolQueryBuilder bqb=QueryBuilders.boolQuery();
            float BOOST = (float) 1.2;
            MatchQueryBuilder titleSearchBuilder = QueryBuilders.matchQuery("name", "张中国");
            titleSearchBuilder.boost(BOOST);
            titleSearchBuilder.operator(Operator.AND);
            bqb.must(titleSearchBuilder);
            //模糊搜索数据
            SearchResponse response = client.prepareSearch("user").setTypes("userInfo")
                    .setQuery(bqb.toString())
                    .setFrom(0).setSize(60).setExplain(true) //setExplain 按查询匹配度排序
                    .execute()
                    .actionGet();
            SearchHits hits = response.getHits();
            System.out.println(hits.getTotalHits() +" "+ hits.getHits().length);
            //打印搜索结果
            for (int i = 0; i < hits.getHits().length; i++) {
                System.out.println("===searchMatchQuery()==="+hits.getAt(i).getId()+"--" +
                        "-----------"+hits.getAt(i).getSource());
            }
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

  修改数据

 

  • 了解 elasticsearch 的修改的底层逻辑
  • java 实现 elasticsearch 修改单条数据
  • java 实现 elasticsearch 批量修改多条数据

 

  • elasticsearch 修改在内部,修改标记旧文档为删除(增加了一个 version 版本号)并添加了一个完整的新文档。旧版本文档不会立即消失,但你也不能去访问它。
  • elasticsearch 会在你继续索引更多数据时清理被删除的文档,或者进行强制清除命令把这种过期的旧数据删除掉。因为这种过期旧数据太多在一定程度上将会影响查询效率。
  • 有时候我们修改的内容非常多,达到索引的 80% 上时,会考虑索引重建即 reindex,索引重建有点相当于删除表重新添加数据的感觉。

 

package com.syl.es;

import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

public class UpdateData {

    /**
     * @param args
     */
    public static void main(String[] args) {
        updateEs();
    }

    /**
     * 更新索引
     */
    public static void updateEs(){
        //索引服务的地址
        String elasticServer= "192.168.154.129";
        //索引服务的端口
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            //初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(
                            InetAddress.getByName(elasticServer), elasticServerPort));
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            //设置更新的字段
            XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
                    .startObject()
                    .field("name","王美丽")
                    .field("nickname","美丽")
                    .field("birthdate",df.format(new Date()))
                    .endObject();
            //更新为1的字段数据
            UpdateResponse response=client.prepareUpdate("user","userInfo","1")
                    .setDoc(jsonBuilder)
                    .get();
            String _index = response.getIndex();
            String _type = response.getType();
            String _id = response.getId();
            long _version = response.getVersion();
            boolean created = response.isCreated();
            System.out.println(_index+" "+_type+" "+_id+" "+_version+" "+created);
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  

 

 

 

 

批量更新

 /**
     * 批量更新索引数据
     */
    public static void batchUpdateEs(){
        String elasticServer= "192.168.154.129";
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(
                            InetAddress.getByName(elasticServer), elasticServerPort));
            //初始化数据
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            List dataList = new ArrayList();
            Map dataMap1=new HashMap();
            dataMap1.put("name","张中国");
            dataMap1.put("nickname", "张中");
            dataMap1.put("nativeplace", "上海静安寺");
            dataMap1.put("address", "上海静安寺1街坊10栋");
            dataMap1.put("birthdate", "1980-02-15");
            dataMap1.put("id", "2");
            Map dataMap2=new HashMap();
            dataMap2.put("name","张三丰");
            dataMap2.put("nickname", "张三");
            dataMap2.put("nativeplace", "上海静安寺");
            dataMap2.put("address", "上海静安寺1街坊10栋");
            dataMap2.put("birthdate", "2018-01-23");
            dataMap2.put("id", "3");
            dataList.add(dataMap1);
            dataList.add(dataMap2);
            BulkRequestBuilder bulkRequest = client.prepareBulk();
            int y=dataList.size();
            //执行批量更新
            for(int i=0;i<y;i++){
                Map<String, Object> m =(Map<String, Object>) dataList.get(i);
                XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name",m.get("name").toString())
                        .field("nickname",m.get("nickname").toString())
                        .field("nativeplace",m.get("nativeplace").toString())
                        .field("address",m.get("address").toString())
                        .field("birthdate",m.get("birthdate").toString())
                        .endObject();
                bulkRequest.add(client.prepareUpdate("user", "userInfo",m.get("id").toString())
                        .setDoc(jsonBuilder));
                
                if (i % 10000 == 0) {
                    bulkRequest.execute().actionGet();
                }
            }
            bulkRequest.execute().actionGet();
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();


} }

  

elasticsearch 删除数据

  • 了解 elasticsearch 的删除的底层逻辑
  • java 实现 elasticsearch 删除单条数据
  • java 实现 elasticsearch 删除多条数据
  • elasticsearch 删除在内部,删除文档的语法模式与之前基本一致,只不过要使用 DELETE 方法:DELETE /user/info/1 如果文档被找到,Elasticsearch 将返回 200 OK 状态码和以下响应体。注意_version 数字已经增加了。删除一个文档也不会立即从磁盘上移除,它只是被标记成已删除。Elasticsearch 将会在你之后添加更多索引的时候才会在后台进行删除内容的清理。
  • 有时候我们删除的内容非常多,达到索引的 80% 上时,会考虑索引重建即 reindex,这时直接删除 index 是非常快的,类似于删除表的操作。
package com.syl.es;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;

public class DeleteData {

    public static void main(String args[]){
        deleteEs();
    }
    /**
     * 删除索引数据
     */
    public static void deleteEs(){
        //索引服务的地址
        String elasticServer= "192.168.154.129";
        //索引服务的端口
        Integer elasticServerPort = 9300;
        Client client=null;
        try{
            //初始化连接
            Settings settings = Settings.settingsBuilder().build();
            client = TransportClient.builder().settings(settings).build()
                    .addTransportAddress(new InetSocketTransportAddress(
                            InetAddress.getByName(elasticServer), elasticServerPort));
            //删除为1的索引数据
            client.prepareDelete("user","userInfo","1").execute().actionGet();
            //关闭连接
            client.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}