ElasticSearch学习笔记

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

在Centos7中安装elasticsearch5.5

第一步:必须有jre支持

Elasticsearch时用java实现的,运行elasticsearch必须有jre的支持,所以要先安装jre

第二步:下载elasticsearch

https://www.elastic.co/cn/downloads/past-releases/#elasticsearch

因为是centos中运行,所以需要选择tar.gz压缩包

下载后使用ftp上传到centos中/home/data目录下,如果没有data目录需要新建一下

ElasticSearch学习笔记_第1张图片

上传到/home/data/目录下,没有就创建

第三步:解压缩

[root@localhost ~]# cd /home/data

[root@localhost data]# tar -zxvf elasticsearch-5.5.2.tar.gz

……

第四步:在/home/目录下创建es目录,将解压缩后elasticsearch-5.5.2剪切到es目录下

[root@localhost home]# mv /home/data/elasticsearch-5.5.2 /home/es

 

第五步:运行elasticsearch

[root@localhost es]# cd elasticsearch-5.5.2

[root@localhost elasticsearch-5.5.2]# ll

总用量 224

drwxr-xr-x.  2 root root   4096 11月 19 21:46 bin

drwxr-xr-x.  2 root root     75 8月  14 2017 config

drwxr-xr-x.  2 root root   4096 8月  14 2017 lib

-rw-r--r--.  1 root root  11358 8月  14 2017 LICENSE.txt

drwxr-xr-x. 13 root root    236 8月  14 2017 modules

-rw-r--r--.  1 root root 194187 8月  14 2017 NOTICE.txt

drwxr-xr-x.  2 root root      6 8月  14 2017 plugins

-rw-r--r--.  1 root root   9549 8月  14 2017 README.textile

 

以上内容可以看到,所需的启动文件在bin目录下

 

[root@localhost elasticsearch-5.5.2]# sh bin/elasticsearch   启动elasticsearch

 

此时会报错

[2019-11-19T22:01:48,806][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]

org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root

        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:127) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:114) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:67) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:122) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.cli.Command.main(Command.java:88) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:91) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:84) ~[elasticsearch-5.5.2.jar:5.5.2]

Caused by: java.lang.RuntimeException: can not run elasticsearch as root

        at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:106) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:194) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:351) ~[elasticsearch-5.5.2.jar:5.5.2]

        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:123) ~[elasticsearch-5.5.2.jar:5.5.2]

        ... 6 more

查询百度得到结论,不能使用root权限启动,只能创建一个用户,授权后才能启动

[root@localhost elasticsearch-5.5.2]# useradd elastic  创建账户

[root@localhost elasticsearch-5.5.2]# chown -R elastic:elastic /home/es/elasticsearch-5.5.2/   授权

[root@localhost elasticsearch-5.5.2]# su elastic  切换用户

[elastic@localhost elasticsearch-5.5.2]$

 

第六步:使用用户elastic启动elasticsearch

[elastic@localhost elasticsearch-5.5.2]$ sh bin/elasticsearch

出来一大串info说明elasticsearch启动成功了,但是这种方式是前台运行,不方便我们进行其他的操作,需要在后面加入 –d转为后台运行,先ctrl+c退出执行

ElasticSearch学习笔记_第2张图片

[elastic@localhost elasticsearch-5.5.2]$ sh bin/elasticsearch –d  后台运行

第七步:检查是否后台运行,出现后面一大串内容说明已经运行

[elastic@localhost elasticsearch-5.5.2]$ ps -ef | grep elasticsearch

elastic    4023      1  9 22:18 pts/1    00:00:17 /usr/local/java/jdk1.8.0_221/bin/java -Xms2g -Xmx2g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+AlwaysPreTouch -server -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -Djdk.io.permissionsUseCanonicalPath=true -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j.skipJansi=true -XX:+HeapDumpOnOutOfMemoryError -Des.path.home=/home/es/elasticsearch-5.5.2 -cp /home/es/elasticsearch-5.5.2/lib/* org.elasticsearch.bootstrap.Elasticsearch -d

elastic    4104   3750  0 22:21 pts/1    00:00:00 grep --color=auto elasticsearch

第八步:测试本地是否可以访问

[elastic@localhost elasticsearch-5.5.2]$ curl http://localhost:9200

{

  "name" : "HkLIHs6",

  "cluster_name" : "elasticsearch",

  "cluster_uuid" : "DtfgC_JPR4SbmtZbTJ0sKQ",

  "version" : {

    "number" : "5.5.2",

    "build_hash" : "b2f0c09",

    "build_date" : "2017-08-14T12:33:14.154Z",

    "build_snapshot" : false,

    "lucene_version" : "6.6.0"

  },

  "tagline" : "You Know, for Search"

}

[elastic@localhost elasticsearch-5.5.2]$

如果出现无法访问的情况,大部分是防火墙需要关闭

 

第九步:允许外网连接

修改/home/es/elasticsearch/config/elasticsearch.yml文件

[elastic@localhost elasticsearch-5.5.2]$ vi config/elasticsearch.yml

 

ElasticSearch学习笔记_第3张图片

去掉这两个地方的备注,network.host修改为本机的IP地址

 

修改完毕后,首先尝试前台启动,有可能会报错

[elastic@localhost elasticsearch-5.5.2]$ sh bin/elasticsearch

 

ERROR: [2] bootstrap checks failed

[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]

[2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]

最大描述符过低

切换到root权限才能修改

[root@localhost ~]# vi /etc/security/limits.conf  退到root的根目录下修改文件

ElasticSearch学习笔记_第4张图片

在最后一行加入

*                hard    nofile          65536

*                hard    nofile          65536

[2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 虚拟内存过低

切换到root权限才能修改

[root@localhost ~]# vi /etc/sysctl.conf

ElasticSearch学习笔记_第5张图片

在配置文件中加入  vm.max_map_count=2621441

保存退出后,使之永久生效

[root@localhost ~]# vi /etc/sysctl.conf

[root@localhost ~]# sudo sysctl -p /etc/sysctl.conf

vm.max_map_count = 2621441

[root@localhost ~]#

切换用户elastic后重新启动elasticsearch

[elastic@localhost elasticsearch-5.5.2]$ sh bin/elasticsearch

如果启动成功后,使用ctrl+c终止服务,使用后台启动

[elastic@localhost elasticsearch-5.5.2]$ sh bin/elasticsearch -d

查看是否启动完成

[elastic@localhost elasticsearch-5.5.2]$ ps -ef | grep elasticsearch

如果出现一大串内容,说明启动完成

 

测试本地是否可以访问

[elastic@localhost elasticsearch-5.5.2]$ curl http://192.168.70.129:9200   配置文件中的ip地址

{

  "name" : "HkLIHs6",

  "cluster_name" : "elasticsearch",

  "cluster_uuid" : "DtfgC_JPR4SbmtZbTJ0sKQ",

  "version" : {

    "number" : "5.5.2",

    "build_hash" : "b2f0c09",

    "build_date" : "2017-08-14T12:33:14.154Z",

    "build_snapshot" : false,

    "lucene_version" : "6.6.0"

  },

  "tagline" : "You Know, for Search"

}

[elastic@localhost elasticsearch-5.5.2]$

测试外网是否可访问

ElasticSearch学习笔记_第6张图片

外网依旧无法访问

防火墙需要关闭

切换为root权限,查看防火墙状态

[root@localhost elasticsearch-5.5.2]# firewall-cmd --state  查看防火墙的状态

running

[root@localhost elasticsearch-5.5.2]#

可以看到防火墙处于运行状态

关闭防火墙

[root@localhost elasticsearch-5.5.2]# systemctl stop firewalld.service   关闭防火墙

[root@localhost elasticsearch-5.5.2]# systemctl disable firewalld.service  禁用防火墙

Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.

Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

[root@localhost elasticsearch-5.5.2]# firewall-cmd --state

not running

[root@localhost elasticsearch-5.5.2]#

再次使用外网访问elasticsearch

ElasticSearch学习笔记_第7张图片

 

 

利用java接口创建索引以及操作文档

测试1:连接ElasticSearch

创建Maven项目,jar基础包

pom.xml

<dependencies>

   

    <dependency>

        <groupId>org.elasticsearch.clientgroupId>

        <artifactId>transportartifactId>

        <version>5.5.2version>

    dependency>

   

    <dependency>

        <groupId>com.google.code.gsongroupId>

        <artifactId>gsonartifactId>

        <version>2.8.2version>

    dependency>

   

    <dependency>

        <groupId>junitgroupId>

        <artifactId>junitartifactId>

        <version>4.12version>

        <scope>testscope>

    dependency>

dependencies>

创建连接测试文件TestConnection.java

package com.kingsoft.unit01;

 

import java.net.InetAddress;

 

import org.elasticsearch.client.transport.TransportClient;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.common.transport.InetSocketTransportAddress;

import org.elasticsearch.transport.client.PreBuiltTransportClient;

/**

 *

 * @ClassName: TestConnection

 * @Description: TODO (测试连接elasticsearch)

 * @author 北派二大爷

 * @date 20191120日下午10:33:11

 */

public class TestConnection {

   

    //服务器地址

    private static String host = "192.168.70.129";

    //elasticsearch对外开放的端口

    private static int port = 9300;

   

    public static void main(String[] args)throws Exception{

       

        @SuppressWarnings("resource")

        TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)

                                                         .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));

        System.out.println(client);

        client.close();

    }

}

创建索引,以及增删改查文档操作

package com.kingsoft.unit01;

 

import java.net.InetAddress;

 

import org.elasticsearch.action.delete.DeleteResponse;

import org.elasticsearch.action.get.GetResponse;

import org.elasticsearch.action.index.IndexResponse;

import org.elasticsearch.action.update.UpdateResponse;

import org.elasticsearch.client.transport.TransportClient;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.common.transport.InetSocketTransportAddress;

import org.elasticsearch.common.xcontent.XContentType;

import org.elasticsearch.transport.client.PreBuiltTransportClient;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

import com.google.gson.JsonObject;

 

public class TestIndexer {

 

    // 服务器地址

    private static String host = "192.168.70.129";

    // elasticsearch对外开放的端口

    private static int port = 9300;

    private TransportClient client = null;

 

    /**

     *

     * Description

     * (启动时初始化)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:16:44

     */

    @Before

    @SuppressWarnings("resource")

    public void setUp() throws Exception {

        client = new PreBuiltTransportClient(Settings.EMPTY)

                .addTransportAddress(new InetSocketTransportAddress

(InetAddress.getByName(host), port));

    }

 

    /**

     *

     * Description

     * (结束时关闭)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:16:57

     */

    @After

    public void destroy() {

        if (client != null) {

            client.close();

        }

    }

 

    /**

     *

     * Description

     * (创建索引并添加文档)

     * -------------------------------------------------

     * 北派二大爷 20191120 下午10:49:54

     */

    @Test

    public void testIndexCreate() throws Exception {

        JsonObject jsonObject = new JsonObject();

        jsonObject.addProperty("name", "java从入门到转行");

        jsonObject.addProperty("publishDate", "2010-10-23");

        jsonObject.addProperty("price", 100);

 

        IndexResponse response = client.prepareIndex("book", "java", "1").setSource(jsonObject.toString(), XContentType.JSON).get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("当前实例状态:" + response.status());

    }

 

    /**

     *

     * Description

     * (根据Id获取文档)

     * -------------------------------------------------

     * 北派二大爷 20191120 下午10:57:28

     */

    @Test

    public void testGetDocument() throws Exception {

        GetResponse response = client.prepareGet("book", "java", "1").get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("Json格式:" + response.getSourceAsString());

    }

 

    /**

     *

     * Description

     * (根据Id修改文档)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:05:47

     */

    @Test

    public void testUpdate() throws Exception {

        JsonObject jsonObject = new JsonObject();

        jsonObject.addProperty("name", "java编程思想");

        jsonObject.addProperty("publishDate", "2019-11-23");

        jsonObject.addProperty("price", 108);

        UpdateResponse response = client.prepareUpdate("book", "java", "1").setDoc(jsonObject.toString(), XContentType.JSON).get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("当前实例状态:" + response.status());

    }

    /**

     *

     * Description

     * (根据Id删除文档)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:09:15

     */

    @Test

    public void testDelete()throws Exception{

        DeleteResponse response = client.prepareDelete("book", "java", "1").get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("当前实例状态:" + response.status());

    }

 

}

 

 

Elasticsearch安装head插件

第一步:安装nodejs,head插件时nodejs实现的,所以必须先安装nodejs

http://nodejs.cn/download/

 

ElasticSearch学习笔记_第8张图片

有两种方式获取到tar包

  1. 直接下载并拷贝到/usr/local目录下使用
  2. 使用wget方式在线获取包node-v8.9.4-linux-x64.tar.xz

[root@localhost local]# wget https://npm.taobao.org/mirrors/node/v8.9.4/node-v8.9.4-linux-x64.tar.xz

解压缩下载的tar.xz包

[root@localhost local]# tar -xJf node-v8.9.4-linux-x64.tar.xz

ElasticSearch学习笔记_第9张图片

配置环境变量

[root@localhost local]# vi /etc/profile

 

加入以下内容在JAVA_HOME下面保存退出

export NODE_HOME=/usr/local/node-v8.9.4-linux-x64

export PATH=$NODE_HOME/bin:$PATH

ElasticSearch学习笔记_第10张图片

 

使配置生效

[root@localhost local]# vi /etc/profile

[root@localhost local]# source /etc/profile

[root@localhost local]#

 

查看node和npm的版本

 [root@localhost local]# node -v

v8.9.4

[root@localhost local]# npm -v

5.6.0

第二步:安装Git,是一个分布式版本控制系统

使用yum命令下载Git

[root@localhost local]# yum install -y git

 

下载完毕后查看版本

 [root@localhost local]# git --version

git version 1.8.3.1

 

卸载命令

yum remove git

第三步:下载以及安装head插件

https://github.com/mobz/elasticsearch-head

ElasticSearch学习笔记_第11张图片

按照以上的步骤进行安装

[root@localhost local]# git clone git://github.com/mobz/elasticsearch-head.git

 

下载完成后会生成elasticsearch-head文件夹

ElasticSearch学习笔记_第12张图片

 

进入文件夹,安装npm(使用淘宝镜像)

[root@localhost elasticsearch-head]# npm config set registry https://registry.npm.taobao.org

[root@localhost elasticsearch-head]# npm config get registry

https://registry.npm.taobao.org/

[root@localhost elasticsearch-head]#

 

安装npm

[root@localhost elasticsearch-head]# npm install

 

配置elasticsearch-5.5.2的elasticsearch.yml配置文件使之关联head插件

[root@localhost elasticsearch-head]# vi /home/es/elasticsearch-5.5.2/config/elasticsearch.yml

配置内容

http.cors.enabled: true

http.cors.allow-origin: "*"

 

ElasticSearch学习笔记_第13张图片

 

启动elasticsearch

切换用户elastic

[elastic@localhost elasticsearch-head]$ sh /home/es/elasticsearch-5.5.2/bin/elasticsearch -d

 

测试是否启动成功

[elastic@localhost elasticsearch-head]$ ps -ef | grep elasticsearch

如果出现一大串字符说明启动成功

启动Head插件

[elastic@localhost elasticsearch-head]$ npm run start

 

> [email protected] start /usr/local/elasticsearch-head

> grunt server

 

>> Local Npm module "grunt-contrib-jasmine" not found. Is it installed?

(node:3890) ExperimentalWarning: The http2 module is an experimental API.

 

Running "connect:server" (connect) task

Waiting forever...

Started connect web server on http://localhost:9100

 

使用浏览器192.168.70.131:9100

ElasticSearch学习笔记_第14张图片

说明head插件已经可以使用了

 

ElasticSearch学习笔记_第15张图片

 

访问192.168.70.131服务下的9200(elasticsearch)端口,如果之前创建过索引就会出现下面的值,集群健康值为黄色说明elasticsearch和head关联正常

查看其中的内容

ElasticSearch学习笔记_第16张图片

Unassigned为未分配的备份

gFMNHCO为5个分片

Elasticsearch提供了丰富的http url接口对外提供服务,这也使得elasticsearch插件特别多,功能也强大。

添加索引的方式一

ElasticSearch学习笔记_第17张图片

单击“复合查询”在查询地址栏中输入http://192.168.70.131:9200/student/

修改提交方式为PUT,单击提交请求,即可生成student的索引

查看方式1

ElasticSearch学习笔记_第18张图片

 

查看方式2

ElasticSearch学习笔记_第19张图片

 

添加索引的方式二(比较简单)

ElasticSearch学习笔记_第20张图片

单击索引选项卡,点击“新建索引”

索引名称:不用解释

分片数:10(比如将1000W的数据量分成10份)

副本数:2(备份的数量)

单击“ok”即可完成创建索引

查看索引的创建情况

ElasticSearch学习笔记_第21张图片

 

删除索引

ElasticSearch学习笔记_第22张图片

单击“动作”à 删除

出现对话框,需要输入“删除”才能完成删除操作

添加文档(要先有索引,然后才能添加文档

ElasticSearch学习笔记_第23张图片

单击“数据浏览”可以看到索引为book,类型为java

ElasticSearch学习笔记_第24张图片

单击“复合查询”后的小加号,在查询栏中输入http://192.168.70.131:9200/book/java/

为book索引中java类型添加文档,文档的形式是以JSON串的方式输入,正常的习惯是单击验证JSON,如果没有出现红色提示说明语法正确,然后单击“提交请求”,出现右侧的信息说明文档已经添加完毕。

 

单击“数据浏览”即可看到添加的文档

ElasticSearch学习笔记_第25张图片

修改文档(首先要先知道要修改文档的_id)

ElasticSearch学习笔记_第26张图片

单击要修改的内容,即可出现对话框,直接复制_id主键

ElasticSearch学习笔记_第27张图片

将得到的_id值拷贝到/book/java/后面,提交方式POST,修改JSON内容,单击“提交请求”

从右侧图中可以看到version为2,说明修改后的第二版

 

查询文档(首先要先知道要查询文档的_id)

ElasticSearch学习笔记_第28张图片

将得到的id值复制到/book/java/后面,修改提交方式GET,单击“提交请求”

删除文档(首先要先知道要删除文档的_id)

ElasticSearch学习笔记_第29张图片

将要删除的_id复制到/book/java/后面,将提交方式修改为DELETE方式,单击“提交请求”即可完成删除

暂时关闭索引

ElasticSearch学习笔记_第30张图片

单击“动作”,选择关闭即可将暂时不用的索引关闭(不是删除),这时如果对这个索引进行CRUD时就会报错。

将关闭的索引开启

ElasticSearch学习笔记_第31张图片

ElasticSearch的数据类型

  1. keyword:相当于string类型,适合短词汇内容,例如姓名,邮件,性别等等
  2. text:适合长文本,可以进行分词,比如文章标题,文章的内容等。
  3. Integer类型:int
  4. Date类型

创建索引student

ElasticSearch学习笔记_第32张图片

向索引中添加字段(使用PUT方式提交)

ElasticSearch学习笔记_第33张图片

内容如下

{

"mappings":{

      "first":{

           "properties":{

                 "name":{"type":"keyword"},

                 "brithday":{"type":"date"},

                 "age":{"type":"integer"},

                 "name":{"type":"keyword"},

                 "desc":{"type":"text"}

           }

      }

}

}

向student索引中添加一些值

ElasticSearch学习笔记_第34张图片

提交时以POST方式,索引为student,类型为first,不指定Id

查看student索引的映射关系

ElasticSearch学习笔记_第35张图片

向student索引添加字段

ElasticSearch学习笔记_第36张图片

Elasticsearch多机集群的配置

第一步:第一虚拟机作为主机修改/home/es/elasticsearch-5.5.2/config/elasticsearch.yml

ElasticSearch学习笔记_第37张图片

将集群名称和节点名称的注释去掉,也可以重新命名

 

ElasticSearch学习笔记_第38张图片

按照以前配置的ip地址,和端口号不变

ElasticSearch学习笔记_第39张图片

发现节点设置为当前ip地址192.168.70.131

配置好后将这个虚拟机克隆

需要在Vmware上再创建一个Centos7,但Vmware提供了一种克隆技术

单击工具栏的“虚拟机"-->"管理"--> “克隆”

ElasticSearch学习笔记_第40张图片

单击下一步

ElasticSearch学习笔记_第41张图片

单击下一步

ElasticSearch学习笔记_第42张图片

修改为“创建完整克隆”单击下一步

ElasticSearch学习笔记_第43张图片

选择克隆文件的位置,单击“完成”

ElasticSearch学习笔记_第44张图片

克隆完成后就会出现两个虚拟机,除了ip不同,其他的内容和配置完全相同

本次测试使用的设置

主机:192.168.70.131     node-1(节点名称)   my-application(集群名称)

副主机: 192.168.70.130   node-2(节点名称)   my-application(集群名称)

 

修改副主机的elasticsearch.yml配置文件

ElasticSearch学习笔记_第45张图片

node.name: node-2

network.host: 192.168.70.130

其他的配置不变

注意:

配置集群之前,先要把集群的节点里data目录下的Node目录删除,否则创建集群时会报错

192.168.70.131

ElasticSearch学习笔记_第46张图片

data目录下的Node目录删除

192.168.70.130

ElasticSearch学习笔记_第47张图片

data目录下的Node目录删除

启动步骤:

首先要启动主机 192.168.70.131

  1. 使用elastic用户登录 
  2. 启动elasticsearch
  3. 使用root用户登录
  4. 启动elasticsearch-head

然后启动副主机 192.168.70.130

  1. 使用elastic用户登录
  2. 启动elasticsearch

主机和副主机启动后登录

ElasticSearch学习笔记_第48张图片

显示出2个节点,说明集群配置完成

使用Java测试集群是否可联

package com.kingsoft.unit01;

 

import java.net.InetAddress;

 

import org.elasticsearch.client.transport.TransportClient;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.common.transport.InetSocketTransportAddress;

import org.elasticsearch.transport.client.PreBuiltTransportClient;

 

/**

 *

 * @ClassName: TestConnection

 * @Description: TODO (测试连接elasticsearch)

 * @author 北派二大爷

 * @date 20191120日下午10:33:11

 */

public class TestConnection {

 

    // 服务器地址

    private static String host = "192.168.70.131";

    // elasticsearch对外开放的端口

    private static int port = 9300;

    // 集群的名称

    public static final String CLUSTER_NAME = "my-application";

      // 集群配置信息cluster.name=my-application

    private static Settings.Builder settings = Settings.builder().put("cluster.name", CLUSTER_NAME);

 

    public static void main(String[] args) throws Exception {

 

        @SuppressWarnings("resource")

        TransportClient client = new PreBuiltTransportClient(settings.build())

                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));

        System.out.println(client);

        client.close();

    }

}

使用Java测试集群中创建,查询,修改,删除索引

package com.kingsoft.unit01;

 

import java.net.InetAddress;

 

import org.elasticsearch.action.delete.DeleteResponse;

import org.elasticsearch.action.get.GetResponse;

import org.elasticsearch.action.index.IndexResponse;

import org.elasticsearch.action.update.UpdateResponse;

import org.elasticsearch.client.transport.TransportClient;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.common.transport.InetSocketTransportAddress;

import org.elasticsearch.common.xcontent.XContentType;

import org.elasticsearch.transport.client.PreBuiltTransportClient;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

import com.google.gson.JsonObject;

 

public class TestIndexer {

 

    // 服务器地址

    private static String host = "192.168.70.131";

    // elasticsearch对外开放的端口

    private static int port = 9300;

    private TransportClient client = null;

    //集群的名称

    public static final String CLUSTER_NAME = "my-application";

    private static Settings.Builder settings = Settings.builder().put("cluster.name", CLUSTER_NAME);

 

    /**

     *

     * Description

     * (启动时初始化)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:16:44

     */

    @Before

    @SuppressWarnings("resource")

    public void setUp() throws Exception {

        client = new PreBuiltTransportClient(settings.build())

                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));

    }

 

    /**

     *

     * Description

     * (结束时关闭)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:16:57

     */

    @After

    public void destroy() {

        if (client != null) {

            client.close();

        }

    }

 

    /**

     *

     * Description

     * (创建索引并添加文档)

     * -------------------------------------------------

     * 北派二大爷 20191120 下午10:49:54

     */

    @Test

    public void testIndexCreate() throws Exception {

        JsonObject jsonObject = new JsonObject();

        jsonObject.addProperty("name", "java从入门到转行");

        jsonObject.addProperty("publishDate", "2010-10-23");

        jsonObject.addProperty("price", 100);

 

        IndexResponse response = client.prepareIndex("book", "java","1").setSource(jsonObject.toString(), XContentType.JSON).get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("当前实例状态:" + response.status());

    }

 

    /**

     *

     * Description

     * (根据Id获取文档)

     * -------------------------------------------------

     * 北派二大爷 20191120 下午10:57:28

     */

    @Test

    public void testGetDocument() throws Exception {

        GetResponse response = client.prepareGet("book", "java", "1").get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("Json格式:" + response.getSourceAsString());

    }

 

    /**

     *

     * Description

     * (根据Id修改文档)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:05:47

     */

    @Test

    public void testUpdate() throws Exception {

        JsonObject jsonObject = new JsonObject();

        jsonObject.addProperty("name", "java编程思想");

        jsonObject.addProperty("publishDate", "2019-11-23");

        jsonObject.addProperty("price", 108);

        UpdateResponse response = client.prepareUpdate("book", "java", "1")

                .setDoc(jsonObject.toString(), XContentType.JSON).get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("当前实例状态:" + response.status());

    }

   

    /**

     *

     * Description

     * (根据Id删除文档)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:09:15

     */

    @Test

    public void testDelete()throws Exception{

        DeleteResponse response = client.prepareDelete("book", "java", "1").get();

        System.out.println("索引名称:" + response.getIndex());

        System.out.println("类型:" + response.getType());

        System.out.println("文档Id:" + response.getId());

        System.out.println("当前实例状态:" + response.status());

    }

}

ElasticSearch查询

创建索引名为film(电影)

创建索引

ElasticSearch学习笔记_第49张图片

创建表头

ElasticSearch学习笔记_第50张图片

内容如下:

{

      "properties":{

           "title":{

                 "type": "text"

           },

           "publishDate":{

                 "type": "date"

           },

           "content":{

                 "type": "text"

           },

           "director":{

                 "type":"keyword"

           },

           "price":{

                 "type":"float"

           }

      }

}

创建测试用的数据

/**

     *

     * Description

     * (创建索引并添加文档)

     * -------------------------------------------------

     * 北派二大爷 20191120 下午10:49:54

     */

    @Test

    public void testIndexCreate() throws Exception {

        JsonArray jsonArray=new JsonArray();

 

        JsonObject jsonObject=new JsonObject();

        jsonObject.addProperty("title", "前任3:再见前任");

        jsonObject.addProperty("publishDate", "2017-12-29");

        jsonObject.addProperty("content", "一对好基友孟云(韩庚 饰)和余飞(郑恺 饰)跟女友都因为一点小事宣告分手,并且拒绝挽回,死不认错。两人在夜店、派对与交友软件上放飞人生第二春,大肆庆祝黄金单身期,从而引发了一系列好笑的故事。孟云与女友同甘共苦却难逃五年之痒,余飞与女友则棋逢敌手相爱相杀无绝期。然而现实的打脸却来得猝不及防:一对推拉纠结零往来,一对纠缠互怼全交代。两对恋人都将面对最终的选择:是再次相见?还是再也不见?");

        jsonObject.addProperty("director", "田羽生");

        jsonObject.addProperty("price", "35");

        jsonArray.add(jsonObject);

 

        JsonObject jsonObject2=new JsonObject();

        jsonObject2.addProperty("title", "机器之血");

        jsonObject2.addProperty("publishDate", "2017-12-29");

        jsonObject2.addProperty("content", "2007年,Dr.James在半岛军火商的支持下研究生化人。研究过程中,生化人安德烈发生基因突变大开杀戒,将半岛军火商杀害,并控制其组织,接管生化人的研究。Dr.James侥幸逃生,只好寻求警方的保护。特工林东(成龙 饰)不得以离开生命垂危的小女儿西西,接受证人保护任务...十三年后,一本科幻小说《机器之血》的出版引出了黑衣生化人组织,神秘骇客李森(罗志祥 饰)(被杀害的半岛军火商的儿子),以及隐姓埋名的林东,三股力量都开始接近一个普通女孩Nancy(欧阳娜娜 饰)的生活,想要得到她身上的秘密。而黑衣人幕后受伤隐藏多年的安德烈也再次出手,在多次缠斗之后终于抓走Nancy。林东和李森,不得不以身犯险一同前去解救,关键时刻却发现李森竟然是被杀害的半岛军火商的儿子,生化人的实验记录也落入了李森之手......");

        jsonObject2.addProperty("director", "张立嘉");

        jsonObject2.addProperty("price", "45");

        jsonArray.add(jsonObject2);

 

        JsonObject jsonObject3=new JsonObject();

        jsonObject3.addProperty("title", "星球大战8:最后的绝地武士");

        jsonObject3.addProperty("publishDate", "2018-01-05");

        jsonObject3.addProperty("content", "《星球大战:最后的绝地武士》承接前作《星球大战:原力觉醒》的剧情,讲述第一军团全面侵袭之下,蕾伊(黛西·雷德利 Daisy Ridley 饰)、芬恩(约翰·博耶加 John Boyega 饰)、波·达默龙(奥斯卡·伊萨克 Oscar Isaac 饰)三位年轻主角各自的抉 择和冒险故事。前作中觉醒强大原力的蕾伊独自寻访隐居的绝地大师卢克·天行者(马克·哈米尔 Mark Hamill 饰),在后者的指导下接受原力训练。芬恩接受了一项几乎不可能完成的任务,为此他不得不勇闯敌营,面对自己的过去。波·达默龙则要适应从战士向领袖的角色转换,这一过程中他也将接受一些血的教训。");

        jsonObject3.addProperty("director", "莱恩·约翰逊");

        jsonObject3.addProperty("price", "55");

        jsonArray.add(jsonObject3);

 

        JsonObject jsonObject4=new JsonObject();

        jsonObject4.addProperty("title", "羞羞的铁拳");

        jsonObject4.addProperty("publishDate", "2017-12-29");

        jsonObject4.addProperty("content", "靠打假拳混日子的艾迪生(艾伦 饰),本来和正义感十足的体育记者马小(马丽 饰)是一对冤家,没想到因为一场意外的电击,男女身体互换。性别错乱后,两人互坑互害,引发了拳坛的大地震,也揭开了假拳界的秘密,惹来一堆麻烦,最终两人在卷莲门副掌门张茱萸(沈腾 饰)的指点下,向恶势力挥起了羞羞的铁拳。");

        jsonObject4.addProperty("director", "宋阳 / 张吃鱼");

        jsonObject4.addProperty("price", "35");

        jsonArray.add(jsonObject4);

 

        JsonObject jsonObject5=new JsonObject();

        jsonObject5.addProperty("title", "战狼2");

        jsonObject5.addProperty("publishDate", "2017-07-27");

        jsonObject5.addProperty("content", "故事发生在非洲附近的大海上,主人公冷锋(吴京 饰)遭遇人生滑铁卢,被开除军籍,本想漂泊一生的他,正当他打算这么做的时候,一场突如其来的意外打破了他的计划,突然被卷入了一场非洲国家叛乱,本可以安全撤离,却因无法忘记曾经为军人的使命,孤身犯险冲回沦陷区,带领身陷屠杀中的同胞和难民,展开生死逃亡。随着斗争的持续,体内的狼性逐渐复苏,最终孤身闯入战乱区域,为同胞而战斗。");

        jsonObject5.addProperty("director", "吴京");

        jsonObject5.addProperty("price", "38");

        jsonArray.add(jsonObject5);

       

        for(int i=0;i<jsonArray.size();i++) {

            JsonObject object = jsonArray.get(i).getAsJsonObject();

            IndexResponse response = client.prepareIndex("film", "dongzuo")

                    .setSource(object.toString(), XContentType.JSON).get();

            System.out.println("索引名称:" + response.getIndex());

            System.out.println("类型:" + response.getType());

            System.out.println("文档Id:" + response.getId());

            System.out.println("当前实例状态:" + response.status());

        }

    }

查询全部(页面操作)

ElasticSearch学习笔记_第51张图片

查询全部带分页(页面操作)

ElasticSearch学习笔记_第52张图片

from 重索引0开始

size每页显示3条

查询全部带排序(页面操作)

ElasticSearch学习笔记_第53张图片

查询全部(指定显示的列)

ElasticSearch学习笔记_第54张图片

只显示title,price

条件查询

ElasticSearch学习笔记_第55张图片

查询电影名中有“战”字

查询结果关键字高亮显示

源码:

 

{

      "query":{

           "match":{"title":"战"}

      },

      "_source":{

           "include":["title","price"]

      },

      "highlight":{

           "fields":{"title":{}}

      }

}

以上查询对应的java代码

package com.kingsoft.unit01;

 

import java.net.InetAddress;

 

import org.elasticsearch.action.search.SearchRequestBuilder;

import org.elasticsearch.action.search.SearchResponse;

import org.elasticsearch.client.transport.TransportClient;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.common.transport.InetSocketTransportAddress;

import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.search.SearchHit;

import org.elasticsearch.search.SearchHits;

import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;

import org.elasticsearch.search.sort.SortOrder;

import org.elasticsearch.transport.client.PreBuiltTransportClient;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

/**

 *

 * @ClassName: TestSearch

 * @Description: TODO (查询练习)

 * @author 北派二大爷

 * @date 2019年11月28日下午9:41:31

 */

public class TestSearch {

 

      // 服务器地址

      private static String host = "192.168.70.131";

      // elasticsearch对外开放的端口

      private static int port = 9300;

      private TransportClient client = null;

      //集群的名称

      public static final String CLUSTER_NAME = "my-application";

      private static Settings.Builder settings = Settings.builder().put("cluster.name", CLUSTER_NAME);

 

      /**

       *

       * Description

       * (启动时初始化)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月20日 下午11:16:44

       */

      @Before

      @SuppressWarnings("resource")

      public void setUp() throws Exception {

           client = new PreBuiltTransportClient(settings.build())

                 .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));

      }

 

      /**

       *

       * Description

       * (结束时关闭)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月20日 下午11:16:57

       */

      @After

      public void destroy() {

           if (client != null) {

                 client.close();

           }

      }

          

      /**

       *

       * Description

       * (查询全部)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月28日 下午9:42:19

       */

      @Test

      public void searchAll()throws Exception{

           SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

           SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())

                            .execute()       //执行

                            .actionGet();    //查询所有

           SearchHits hits = sr.getHits();

           for(SearchHit hit : hits) {

                 System.out.println(hit.getSourceAsString());

           }

      }

     

      /**

       *

       * Description

       * (查询全部带分页)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月28日 下午10:02:59

       */

      @Test

      public void searchPaging()throws Exception{

           SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

           SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())

                            .setFrom(0) //索引从0开始

                            .setSize(3) //每页显示3条记录

                            .execute() //执行

                            .actionGet(); //查询所有

           SearchHits hits = sr.getHits();

           for(SearchHit hit : hits) {

                 System.out.println(hit.getSourceAsString());

           }

      }

          

      /**

       *

       * Description

       * (查询全部带排序)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月28日 下午10:11:07

       */

      @Test

      public void searchSort()throws Exception{

           SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

           SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())

                            .addSort("publishDate", SortOrder.DESC)        //根据上映日期降序排列

                            .execute() //执行

                            .actionGet(); //查询所有

           SearchHits hits = sr.getHits();

           for(SearchHit hit : hits) {

                 System.out.println(hit.getSourceAsString());

           }

      }

          

      /**

       *

       * Description

       * (数据列过滤)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月28日 下午10:17:56

       */

      @Test

      public void searchInclude()throws Exception{

           String[] includes = {"title","price"};   //包含显示电影名,票价

           String[] excludes = {"publishDate","content","director"};  //排除显示上映日期,内容简介,导演

           SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

           SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery())

                            //.setFetchSource(includes, null)

                            .setFetchSource(null, excludes)

                            .execute() //执行

                            .actionGet(); //查询所有

           SearchHits hits = sr.getHits();

           for(SearchHit hit : hits) {

                 System.out.println(hit.getSourceAsString());

           }

      }

          

      /**

       *

       * Description

       * (根据条件查询)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月28日 下午10:30:22

       */

      @Test

      public void searchByCondition()throws Exception{

           //包含显示电影名,票价

           String[] includes = {"title","price"};

           SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

           SearchResponse sr = srb.setQuery(QueryBuilders.matchQuery("title", "战"))

                            .setFetchSource(includes, null)

                            .execute() //执行

                            .actionGet(); //查询所有

           SearchHits hits = sr.getHits();

           for(SearchHit hit : hits) {

                 System.out.println(hit.getSourceAsString());

           }

      }

     

      /**

       *

       * Description

       * (根据条件查询并高亮显示)

       *

       * -------------------------------------------------

       * 北派二大爷  2019年11月28日 下午10:37:31

       */

      @Test

      public void searchHighLight()throws Exception{

           //包含显示电影名,票价

           String[] includes = {"title","price"};

           SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

           //定义高亮

           HighlightBuilder highlightBuilder = new HighlightBuilder();

           highlightBuilder.preTags("

"); //前标签

           highlightBuilder.postTags("

"); //后标签

           highlightBuilder.field("title"); //指定高亮字段

           SearchResponse sr = srb.setQuery(QueryBuilders.matchQuery("title", "战"))

                            .highlighter(highlightBuilder) //设置高亮属性

                            .setFetchSource(includes, null)

                            .execute() //执行

                            .actionGet(); //查询所有

           SearchHits hits = sr.getHits();

           for(SearchHit hit : hits) {

                 System.out.println(hit.getSourceAsString()+"高亮内容:"+hit.getHighlightFields());

           }

      }

          

}

复杂查询系列

查询标题匹配“战”的内容

{
  "query": {
    "bool": {
      "must": {
        "match": {"title": "战"}
      }
    }
  }
}  

查询标题中匹配“战”,内容中含有“星球”的内容

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {"title": "战"}
        },
        {
          "match": {"content": "星球"}
        }
      ]
    }
  }
}

bool表示Boolean类型

must表示必须

match表示匹配

使用java代码实现

/**

 *

 * Description

 * (多条件查询)

 *

 * -------------------------------------------------

 * 北派二大爷  20191130 上午8:52:28

 */

@Test

public void searchMulti()throws Exception{

    SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

    QueryBuilder queryBuilder1 = QueryBuilders.matchPhraseQuery("title","");

    QueryBuilder queryBuilder2 = QueryBuilders.matchPhraseQuery("content","星球");

    SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()

                                               .must(queryBuilder1) //加条件

                                               .must(queryBuilder2))

                .setFetchSource(new String[] { "title","price"}, null)

                .execute()

                .actionGet();

    SearchHits hits = sr.getHits();

    for(SearchHit hit : hits) {

        System.out.println(hit.getSourceAsString());

    }

}

包含于不包含结合查询

{

      "query":{

           "bool":{

                 "must":{"match":{"title":"战"}},   //标题中包含“战”

                 "must_not":{"match":{"content":"武士"}}  //内容中不包含“武士”

           }

      }

}

Java代码实现

/**

 *

 * Description

 * (包含于不包含综合查询)

 *

 * -------------------------------------------------

 * 北派二大爷  20191130 上午9:00:21

 */

@Test

public void searchMulti2()throws Exception{

    SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

    QueryBuilder queryBuilder1 = QueryBuilders.matchPhraseQuery("title","");

    QueryBuilder queryBuilder2 = QueryBuilders.matchPhraseQuery("content","武士");

    SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()

                                          .must(queryBuilder1)

                                          .mustNot(queryBuilder2))

            .setFetchSource(new String[] { "title","price"}, null)

            .execute()

            .actionGet();

    SearchHits hits = sr.getHits();

    for(SearchHit hit : hits) {

        System.out.println(hit.getSourceAsString());

    }

}

提高权重加分,使搜索出的排名提前

{

      "query":{

           "bool":{

                 "must":{"match":{"title":"战"}},  //标题中含有“战”

                 "should":[

                      {"match":{"content":"星球"}},   //内容中含有“星球”

                      {"range":{"publishDate":{"gte":"2018-01-01"}}} //上映日期大于2018-01-01

                 ]

           }

      }

}

 

should:满足条件加权重,score得分提高

range:范围       gte:大于

Java代码实现

/**

 *

 * Description

 * (加权提高score得分)

 *

 * -------------------------------------------------

 * 北派二大爷  20191130 上午9:12:41

 */

@Test

public void searchMulti3()throws Exception{

    SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

    QueryBuilder queryBuilder1 = QueryBuilders.matchPhraseQuery("title","");

    QueryBuilder queryBuilder2 = QueryBuilders.matchPhraseQuery("content","星球");

    QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("publishDate").gte("2018-01-01");  //gte:大于

    SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()

            .must(queryBuilder1)

            .should(queryBuilder2)

            .should(queryBuilder3))

            .setFetchSource(new String[] { "title","price","publishDate"}, null)

            .execute()

            .actionGet();

    SearchHits hits = sr.getHits();

    for(SearchHit hit : hits) {

        System.out.println(hit.getScore()+":"+hit.getSourceAsString());

    }

}

查看标题中含有“战”,票价低于40元的电影

{

      "query":{

           "bool":{

                 "must":{

                      "match":{"title":"战"}

                 },

                 "filter":{

                      "range":{"price":{"lte":"40"}}

                 }

           }

      }

}

Java代码实现

/**

 *

 * Description

 * (标题中含有"",票件低于40元的电影)

 *

 * -------------------------------------------------

 * 北派二大爷  20191130 上午9:30:51

 */

@Test

public void searchMulti4()throws Exception{

    SearchRequestBuilder srb = client.prepareSearch("film").setTypes("dongzuo");

    QueryBuilder queryBuilder1 = QueryBuilders.matchPhraseQuery("title","");

    QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("price").lte("40");

    SearchResponse sr = srb.setQuery(QueryBuilders.boolQuery()

            .must(queryBuilder1)

            .filter(queryBuilder2))

            .setFetchSource(new String[] { "title","price","publishDate"}, null)

            .execute()

            .actionGet();

    SearchHits hits = sr.getHits();

    for(SearchHit hit : hits) {

        System.out.println(hit.getSourceAsString());

    }

}

 

中文分词smartcn

首先使用elastic用户登录

进入/home/es/elasticsearch-5.5.2/bin目录下,发现elasticsearch-plugin,运行这个目录进行安装

[elastic@localhost bin]$ sh elasticsearch-plugin install analysis-smartcn

安装完毕后显示

-> Downloading analysis-smartcn from elastic

[=================================================] 100%  

-> Installed analysis-smartcn

[elastic@localhost bin]$

 

 

下载安装完毕后会在elasticsearch-5.5.2/plugins目录下生成一个analysis-smartcn目录

相关的jar和配置文件在里面

重新启动elasticsearch和elasticsearch-head

启动完毕后使用浏览器查看中文分词器是否可用

ElasticSearch学习笔记_第56张图片

可以查看标准分词器是把这五个字逐个拆开,效率不高

ElasticSearch学习笔记_第57张图片

测试smartcn分词效果

{

  "analyzer": "smartcn",

  "text": "我是中国人"

}

可以看到smartcn会把一些关键词组合在一起进行拆分

ElasticSearch学习笔记_第58张图片

测试java代码中使用中文smartcn分词

创建索引film2,给索引film2创建结构

{

    "properties": {

        "title": {

            "type": "text",

       "analyzer": "smartcn"

        },

        "publishDate": {

            "type": "date"

        },

        "content": {

            "type": "text",

       "analyzer": "smartcn"

        },

        "director": {

            "type": "keyword"

        },

        "price": {

            "type": "float"

        }

    }

}

创建测试数据

@Test

    public void testIndexCreate() throws Exception {

        JsonArray jsonArray=new JsonArray();

 

        JsonObject jsonObject=new JsonObject();

        jsonObject.addProperty("title", "前任3:再见前任");

        jsonObject.addProperty("publishDate", "2017-12-29");

        jsonObject.addProperty("content", "一对好基友孟云(韩庚 饰)和余飞(郑恺 饰)跟女友都因为一点小事宣告分手,并且拒绝挽回,死不认错。两人在夜店、派对与交友软件上放飞人生第二春,大肆庆祝黄金单身期,从而引发了一系列好笑的故事。孟云与女友同甘共苦却难逃五年之痒,余飞与女友则棋逢敌手相爱相杀无绝期。然而现实的打脸却来得猝不及防:一对推拉纠结零往来,一对纠缠互怼全交代。两对恋人都将面对最终的选择:是再次相见?还是再也不见?");

        jsonObject.addProperty("director", "田羽生");

        jsonObject.addProperty("price", "35");

        jsonArray.add(jsonObject);

 

        JsonObject jsonObject2=new JsonObject();

        jsonObject2.addProperty("title", "机器之血");

        jsonObject2.addProperty("publishDate", "2017-12-29");

        jsonObject2.addProperty("content", "2007年,Dr.James在半岛军火商的支持下研究生化人。研究过程中,生化人安德烈发生基因突变大开杀戒,将半岛军火商杀害,并控制其组织,接管生化人的研究。Dr.James侥幸逃生,只好寻求警方的保护。特工林东(成龙 饰)不得以离开生命垂危的小女儿西西,接受证人保护任务...十三年后,一本科幻小说《机器之血》的出版引出了黑衣生化人组织,神秘骇客李森(罗志祥 饰)(被杀害的半岛军火商的儿子),以及隐姓埋名的林东,三股力量都开始接近一个普通女孩Nancy(欧阳娜娜 饰)的生活,想要得到她身上的秘密。而黑衣人幕后受伤隐藏多年的安德烈也再次出手,在多次缠斗之后终于抓走Nancy。林东和李森,不得不以身犯险一同前去解救,关键时刻却发现李森竟然是被杀害的半岛军火商的儿子,生化人的实验记录也落入了李森之手......");

        jsonObject2.addProperty("director", "张立嘉");

        jsonObject2.addProperty("price", "45");

        jsonArray.add(jsonObject2);

 

        JsonObject jsonObject3=new JsonObject();

        jsonObject3.addProperty("title", "星球大战8:最后的绝地武士");

        jsonObject3.addProperty("publishDate", "2018-01-05");

        jsonObject3.addProperty("content", "《星球大战:最后的绝地武士》承接前作《星球大战:原力觉醒》的剧情,讲述第一军团全面侵袭之下,蕾伊(黛西·雷德利 Daisy Ridley 饰)、芬恩(约翰·博耶加 John Boyega 饰)、波·达默龙(奥斯卡·伊萨克 Oscar Isaac 饰)三位年轻主角各自的抉 择和冒险故事。前作中觉醒强大原力的蕾伊独自寻访隐居的绝地大师卢克·天行者(马克·哈米尔 Mark Hamill 饰),在后者的指导下接受原力训练。芬恩接受了一项几乎不可能完成的任务,为此他不得不勇闯敌营,面对自己的过去。波·达默龙则要适应从战士向领袖的角色转换,这一过程中他也将接受一些血的教训。");

        jsonObject3.addProperty("director", "莱恩·约翰逊");

        jsonObject3.addProperty("price", "55");

        jsonArray.add(jsonObject3);

 

        JsonObject jsonObject4=new JsonObject();

        jsonObject4.addProperty("title", "羞羞的铁拳");

        jsonObject4.addProperty("publishDate", "2017-12-29");

        jsonObject4.addProperty("content", "靠打假拳混日子的艾迪生(艾伦 饰),本来和正义感十足的体育记者马小(马丽 饰)是一对冤家,没想到因为一场意外的电击,男女身体互换。性别错乱后,两人互坑互害,引发了拳坛的大地震,也揭开了假拳界的秘密,惹来一堆麻烦,最终两人在卷莲门副掌门张茱萸(沈腾 饰)的指点下,向恶势力挥起了羞羞的铁拳。");

        jsonObject4.addProperty("director", "宋阳 / 张吃鱼");

        jsonObject4.addProperty("price", "35");

        jsonArray.add(jsonObject4);

 

        JsonObject jsonObject5=new JsonObject();

        jsonObject5.addProperty("title", "战狼2");

        jsonObject5.addProperty("publishDate", "2017-07-27");

        jsonObject5.addProperty("content", "故事发生在非洲附近的大海上,主人公冷锋(吴京 饰)遭遇人生滑铁卢,被开除军籍,本想漂泊一生的他,正当他打算这么做的时候,一场突如其来的意外打破了他的计划,突然被卷入了一场非洲国家叛乱,本可以安全撤离,却因无法忘记曾经为军人的使命,孤身犯险冲回沦陷区,带领身陷屠杀中的同胞和难民,展开生死逃亡。随着斗争的持续,体内的狼性逐渐复苏,最终孤身闯入战乱区域,为同胞而战斗。");

        jsonObject5.addProperty("director", "吴京");

        jsonObject5.addProperty("price", "38");

        jsonArray.add(jsonObject5);

       

        for(int i=0;i<jsonArray.size();i++) {

            JsonObject object = jsonArray.get(i).getAsJsonObject();

            IndexResponse response = client.prepareIndex("film2", "dongzuo").setSource(object.toString(), XContentType.JSON).get();

            System.out.println("索引名称:" + response.getIndex());

            System.out.println("类型:" + response.getType());

            System.out.println("文档Id:" + response.getId());

            System.out.println("当前实例状态:" + response.status());

        }

    }

 

测试代码

package com.kingsoft.unit01;

 

import java.net.InetAddress;

 

import org.elasticsearch.action.search.SearchRequestBuilder;

import org.elasticsearch.action.search.SearchResponse;

import org.elasticsearch.client.transport.TransportClient;

import org.elasticsearch.common.settings.Settings;

import org.elasticsearch.common.transport.InetSocketTransportAddress;

import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.search.SearchHit;

import org.elasticsearch.search.SearchHits;

import org.elasticsearch.transport.client.PreBuiltTransportClient;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

public class TestPartSearch {

   

    // 服务器地址

    private static String host = "192.168.70.131";

    private static final String ANALYZER = "smartcn";

    // elasticsearch对外开放的端口

    private static int port = 9300;

    private TransportClient client = null;

    //集群的名称

    public static final String CLUSTER_NAME = "my-application";

    private static Settings.Builder settings = Settings.builder().put("cluster.name", CLUSTER_NAME);

 

    /**

     *

     * Description

     * (启动时初始化)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:16:44

     */

    @Before

    @SuppressWarnings("resource")

    public void setUp() throws Exception {

        client = new PreBuiltTransportClient(settings.build())

                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));

    }

 

    /**

     *

     * Description

     * (结束时关闭)

     *

     * -------------------------------------------------

     * 北派二大爷  20191120 下午11:16:57

     */

    @After

    public void destroy() {

        if (client != null) {

            client.close();

        }

    }

   

    /**

     *

     * Description

     * (使用smartcn分词查询)

     *

     * -------------------------------------------------

     * 北派二大爷  20191130 上午11:00:38

     */

    @Test

    public void search1()throws Exception{

        //包含显示电影名,票价

        String[] includes = { "title","price"};

        SearchRequestBuilder srb = client.prepareSearch("film2").setTypes("dongzuo");

        SearchResponse sr = srb.setQuery(QueryBuilders.matchQuery("title", "最后狼").analyzer(ANALYZER))

                    //smartcn会根据“最后”,“狼”的词组进行查询

                    .setFetchSource(includes, null)

                    .execute() //执行

                    .actionGet(); //查询所有

        SearchHits hits = sr.getHits();

        for(SearchHit hit : hits) {

            System.out.println(hit.getSourceAsString());

        }

    }

       

    /**

     *

     * Description

     * (使用smartcn多字段查询)

     *

     * -------------------------------------------------

     * 北派二大爷  20191130 上午11:02:56

     */

    @Test

    public void search2()throws Exception{

        //包含显示电影名,票价

        String[] includes = { "title","price"};

        SearchRequestBuilder srb = client.prepareSearch("film2").setTypes("dongzuo");

        SearchResponse sr = srb.setQuery(QueryBuilders.multiMatchQuery("非洲铁拳星球", "title","content")

             //查询多个字段的多个关键词,smarcn会拆分成“非洲”,“铁拳”,“星球”

            .analyzer(ANALYZER)) //使用smartcn

                .setFetchSource(includes, null) //只显示的字段

                .execute() //执行

                .actionGet(); //查询所有

        SearchHits hits = sr.getHits();

        for(SearchHit hit : hits) {

            System.out.println(hit.getSourceAsString());

        }

    }

}

 

你可能感兴趣的:(ElasticSearch)