Elasticsearch搜索引擎
关键词是中文的建议使用,英文和数字不要,模糊就行
如果普通数据库查询,无法解决如下问题
- 如果表记录上千万上亿了这个性能问题,另外一个如果有一个本文字段要在里面模糊配置,这个就会出现严重的性能问题
- 还不能将搜索词拆分开来,比如模糊搜索名字是“张三”开头的员工,如果想搜出“张小三”那是搜索不出来的。
 总体来说,用数据库来实现搜索,是不太靠谱的,通常性能也会很差
本机使用的话kibana和Elasticsearch都得安装环境和启动
数据可视化工具kibana
Kibana快速入门–》》https://www.jianshu.com/p/e37d0ecef451

docker安装Elasticsearch
Elasticsearch版本必须跟kibana必须一致
本地也有下载,bin/elasticsearch.bat
(1)docker镜像下载
docker pull elasticsearch:5.6.8
docker images
如下图:

(2)安装es容器
docker run -di --name=elasticsearch(别名) -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8
9200端口(Web管理平台端口) 9300(服务默认端口)
浏览器输入地址访问:http://192.168.169.140:9200/

不行的话可以尝试重启linux系统
(3)开启远程连接
上面完成安装后,es并不能正常使用,elasticsearch从5版本以后默认不开启远程连接,程序直接连接会报如下错误:
failed to load elasticsearch nodes : org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{5ttLpMhkRjKLkvoY7ltUWg}{192.168.169.140}{192.168.169.140:9300}]
我们需要修改es配置开启远程连接,代码如下:
登录容器
docker exec -it elasticsearch(别名) /bin/bash
查看目录结构 输入: dir
root@07f22eb41bb5:/elasticsearch路径# dir
NOTICE.txt  README.textile  bin  config  data  lib  logs  modules  plugins
进入config目录
cd config
查看文件
root@07f22eb41bb5:/elasticsearch路径/config# ls
elasticsearch.yml  log4j2.properties  scripts
修改elasticsearch.yml文件
root@07f22eb41bb5:/elasticsearch路径/config vi elasticsearch.yml
bash: vi: command not found
vi命令无法识别,因为docker容器里面没有该命令,我们可以安装该编辑器。
安装vim编辑器
apt-get update
apt-get install vim
安装好了后,修改elasticsearch.yml配置,如下图:
vi elasticsearch.yml
修改如下图:

同时添加下面一行代码:
# 集群结点
cluster.name: my-application
# ip地址改成自己的ip地址,不要写成127.0.0.1
network.host: 192.168.169.140
重启docker
docker restart elasticsearch
(4)系统参数配置
重启后发现重启启动失败了,这时什么原因呢?这与我们刚才修改的配置有关,因为elasticsearch在启动的时候会进行一些检查,比如最多打开的文件的个数以及虚拟内存区域数量等等,如果你放开了此配置,意味着需要打开更多的文件以及虚拟内存,所以我们还需要系统调优
修改vi /etc/security/limits.conf ,追加内容 (nofile是单个进程允许打开的最大文件个数 soft nofile 是软限制 hard nofile是硬限制 )
* soft nofile 65536
* hard nofile 65536
修改vi /etc/sysctl.conf,追加内容 (限制一个进程可以拥有的VMA(虚拟内存区域)的数量 )
vm.max_map_count=655360
执行下面命令 修改内核参数马上生效
sysctl -p
重新启动虚拟机,再次启动容器,发现已经可以启动并远程访问
reboot
(5)跨域配置
修改elasticsearch/config下的配置文件:elasticsearch.yml,增加以下三句命令,并重启:
http.cors.enabled: true
http.cors.allow-origin: "*"
network.host: 192.168.169.140
其中:
 http.cors.enabled: true:此步为允许elasticsearch跨域访问,默认是false。
 http.cors.allow-origin: “*”:表示跨域访问允许的域名地址(表示任意)。
重启
docker restart elasticsearch(别名)
小提示:如果想让容器开机自动启动容器,可以执行下面命令
docker update --restart=always 容器名称或者容器id
etc/elasticsearch中vi jvm.options可以改es运行内存,以下是2g:
-Xms2g
-Xms2g
下载安装IK分词器
(1)安装ik分词器5.6.8,根据ES版本下载
IK分词器下载地址https://github.com/medcl/elasticsearch-analysis-ik/releases
将ik分词器上传到服务器上,然后解压,并改名字为ik
unzip elasticsearch-analysis-ik-5.6.8.zip
mv elasticsearch ik
将ik目录拷贝到docker容器的plugins目录下
docker cp ./ik changgou_elasticsearch:/usr/share/elasticsearch/plugins
(2)IK分词器测试
访问:http://192.168.169.140:9200/_analyze?analyzer=ik_smart&pretty=true&text=我是程序员

访问:http://192.168.169.140:9200/_analyze?analyzer=ik_max_word&pretty=true&text=我是程序员

自定义分词器:
修改IKAnalyzer.cfg.xml配置文件,添加自定义分词文件
自定义停用词汇:
修改IKAnalyzer.cfg.xml配置文件,添加停用词汇
docker安装Kibana
本机打开也有
Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和 Elasticsearch 协作。您可以使用 Kibana 对 Elasticsearch 索引中的数据进行搜索、查看、交互操作。您可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现。
Kibana 可以使大数据通俗易懂。它很简单,基于浏览器的界面便于您快速创建和分享动态数据仪表板来追踪 Elasticsearch 的实时数据变化。
windows本地也有。对应es版本
(1)镜像下载
docker pull docker.io/kibana:5.6.8
(2)安装kibana容器
执行如下命令,开始安装kibana容器
docker run -it -d -e ELASTICSEARCH_URL=http://192.168.169.140:9200 --name kibana(容器名) --restart=always -p 5601:5601 kibana:5.6.8
ELASTICSEARCH_URL=http://192.168.169.140:9200:是指链接的ES地址
restart=always:每次服务都会重启,也就是开启启动
5601:5601:端口号
-e指定环境变量
(3)访问测试
5.6.8版本的
访问http://192.168.169.140:5601如下:

SpringBoot集成
依赖配置
        <!-- ElasticSearch连接 -->
        <dependency>
            <groupId>io.searchbox</groupId>
            <artifactId>jest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
        </dependency>
配置文件elasticsearch.properties,本机默认9200端口
spring.elasticsearch.jest.url=http://localhost:9200
spring.elasticsearch.jest.read-timeout=20000
spring.elasticsearch.jest.connection-timeout=20000
配置类
ElasticsearchConfig
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.config.HttpClientConfig;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
 * Title:Elasticsearch配置类
 * Description:
 * @author WZQ
 * @version 1.0.0
 * @date 2020/2/20
 */
@Data
@Configuration
@ConfigurationProperties(prefix="spring.elasticsearch.jest") // 配置文件前缀
@PropertySource("classpath:elasticsearch.properties") // 引入变量所需配置文件
public class ElasticsearchConfig {
    //自动对应配置文件,名字相同,值自动注入
    private String url;
    private Integer readTimeout;
    private Integer connectionTimeout;
    // 使用引擎注入类
    @Bean
    public JestClient getJestClient(){
        JestClientFactory factory = new JestClientFactory();
        factory.setHttpClientConfig(new HttpClientConfig
                .Builder(this.url)
                .multiThreaded(true)
                .connTimeout(this.connectionTimeout)
                .readTimeout(this.readTimeout)
                .build());
        return factory.getObject();
    }
}
如果有通用配置模块,其他模块引入配置类:
package com.lead.news.article.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
 * Title:引用Elasticsearch
 * Description:
 * @author WZQ
 * @version 1.0.0
 * @date 2020/2/20
 */
@Configuration
@ComponentScan({"com.soft.one.ewms.configuration.elasticsearch"}) //包名
public class EsConfig {
}
引用:
    @Autowired
    private JestClient jestClient;
常数类
commons.constants
/**
 * Title:Elasticsearch用到的常数
 * Description:
 * @author WZQ
 * @version 1.0.0
 * @date 2020/2/20
 */
public class EsConstant {
    // Elasticsearch所有数据类型
    public static String ALL = "_doc";
    // 想当于表名
    public static String INDEX_NAME1 = "自定义1"; 
    
    // 可以加入多个索引库
    // public static String INDEX_NAME1 = "自定义2";
}
添加索引和数据
索引就是搜索时需要匹配字段的集合,可以多个,不需要kinaba也行的,自己代码创建,kinaba只是可视化工具。
import lombok.Data;
import java.util.Date;
/**
 * Title:es文章索引实体类
 * Description:存放到es索引库中,kibana可以查看,这里面字段是有可能被匹配到的字段
 * @author WZQ
 * @version 1.0.0
 * @date 2020/2/1
 */
@Data
public class EsIndexEntity {
    private Long id;
    private String content;
    private Long channelId;
    private Date publishTime;
    private Long status;
    private String title;
    private Long userId;
    // 标识,爬虫还是媒体发布
    private String tag;
}
添加索引和数据到es中,其实索引实体类也可以是数据库的pojo,不用特意写一个也行。
@Log4j2
Class
  @Autowired
  private JestClient jestClient;
  private String ALL = "_doc";//所有数据类型都要上传到索引库
  private String INDEX_NAME1 = "自定义索引名字1"; //可以加入多个索引到库中
  private String INDEX_NAME2 = "自定义索引名字2"; 
    /**
     * 插入50条数据到索引库
     * @throws IOException
     */
    @Test
    public void testSave() throws IOException {
        ArticleHomeDto dto = new ArticleHomeDto();
        dto.setSize(50);
        dto.setTag("__all__");
        List<ApArticle> apArticles = apArticleMapper.loadArticleListByLocation(dto, null);
        // System.out.println(apArticles.size());
        // 插入50条
        for (ApArticle apArticle : apArticles) {
            Example example = new Example(ApArticleContent.class);
            example.createCriteria().andEqualTo("articleId",apArticle.getId());
            ApArticleContent apArticleContent = apArticleContentMapper.selectOneByExample(example);
            EsIndexEntity esIndexEntity = new EsIndexEntity();
            esIndexEntity.setChannelId(new Long(apArticle.getChannelId()));
            esIndexEntity.setContent(ZipUtils.gunzip(apArticleContent.getContent()));
            esIndexEntity.setPublishTime(apArticle.getPublishTime());
            esIndexEntity.setStatus(1L);
            esIndexEntity.setTag("article");
            esIndexEntity.setTitle(apArticle.getTitle());
            
            Index.Builder builder = new Index.Builder(esIndexEntity);//字段都在某一表,那数据库类也行
            builder.id(apArticle.getId().toString());
            builder.refresh(true);
            Index index = builder.index(INDEX_NAME).type(ALL).build();
            try {
                JestResult result = jestClient.execute(index);
                if (result != null && !result.isSucceeded()) {
                //System.out.println("-----");
                throw new RuntimeException(result.getErrorMessage() + "插入更新索引失败!");
            }
            }catch (IOException e) {
                e.printStackTrace();
                log.error("执行ES创建索引失败,message:{}", e.getMessage());
            }
        }
代码使用
@Autowired
private JestClient jestClient; 
private String ALL = "_doc";
private String INDEX_NAME1 = "自定义1"; //可以加入多个索引到库中
private String INDEX_NAME2 = "自定义2";
// 构建查询条件 jestClient
// 根据关键字查询索引库
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 查询条件,字段title匹配,matchQuery模糊搜索,比like高级,关键字的部分词也可以匹配
searchSourceBuilder.query(QueryBuilders.matchQuery("title",dto.getSearchWords()));
// 多个关键词,匹配一个字段,可变数组
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("title", dto.getSearchWords(),dto.getSearchWords2()));
// 设置分页,不设置也没问题
searchSourceBuilder.from(dto.getFromIndex());
// 设置匹配最符合的数据个数,自动把匹配度高的放前面
searchSourceBuilder.size(dto.getPageSize());
Search search = new Search.Builder(searchSourceBuilder.toString())
    .addIndex(INDEX_NAME1) //索引库类型,跟ApArticle类相关
    .addType(ALL)   //查所有类型的数据
    .build();
try {
    // 获取结果
    SearchResult searchResult = jestClient.execute(search);
    // title是ApArticle中的字段,查ApArticle
    List<ApArticle> sourceAsObjectList = searchResult.getSourceAsObjectList(ApArticle.class);
    // 筛选补充字段数据,获取的数据只有title等字段,根据查询的条件字段
    List<ApArticle> resultList = new ArrayList<>();
    for (ApArticle apArticle : sourceAsObjectList) {
        //Example example = new Example(ApArticle.class);           
        //example.createCriteria().andEqualTo("title",apArticle.getTitle());
        apArticle = apArticleMapper.selectOne(apArticle);
        if(apArticle==null){
            continue;
        }
        resultList.add(apArticle);
    }
    return ResponseResult.okResult(resultList);
} catch (IOException e) {
    e.printStackTrace();
}
例子
常数类
/**
 * Title:Elasticsearch用到的常数
 * Description:
 * @author WZQ
 * @version 1.0.0
 * @date 2020/2/20
 */
public class EsConstant {
    // Elasticsearch所有数据类型
    public static String DEFAULT_DOC = "_doc";
    public static String INDEX_LOGIN = "user_login"; //登录档
    // 可以加入多个索引库
    // public static String INDEX_NAME1 = "自定义2";
}
索引映射类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * Title:User_login索引映射
 * Description:
 * @author WZQ
 * @version 1.0.0
 * @date 2020/2/22
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserLoginIndex {
    private Long firstId;
    /**
     * 用户ID,至少6个字符
     */
    private String userId;
    private String equipment;
}
添加数据
@Log4j2
public class LoginSearchEsIndexTest {
    @Autowired
    private JestClient jestClient;
    @Resource
    private LogInService logInService;
    // 添加es索引数据
    @Test
    public void testSave(){
        // 数据库查
        List<LogIn> logIns = logInService.selectAll();
        logIns.forEach(logIn -> {
            // 遍历添加到索引
            UserLoginIndex userLoginIndex = new UserLoginIndex();
            userLoginIndex.setFirstId(logIn.getFirstId());
            userLoginIndex.setUserId(logIn.getUserId());
            userLoginIndex.setEquipment(logIn.getEquipment());
            Index.Builder builder = new Index.Builder(userLoginIndex);//字段都在某一表,那数据库类也行
            builder.refresh(true);
            Index index = builder.index(EsConstant.INDEX_LOGIN).type(EsConstant.DEFAULT_DOC).build();
            try {
                JestResult result = jestClient.execute(index);
                if (result != null){
                    System.out.println("添加索引数据成功");
                }
            }catch (IOException e) {
                e.printStackTrace();
                log.error("执行ES创建索引失败,message:{}", e.getMessage());
            }
        });
    }
}
查询数据
    @Autowired
    private JestClient jestClient;
        List<LogIn> resultList = new ArrayList<>();
        
        // 单条件查询,中文关键词,分词
        // 构建查询条件 jestClient
        // 根据关键字查询索引库
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 查询条件,字段title匹配,matchQuery模糊搜索,比like高级,关键字的部分词也可以匹配
        searchSourceBuilder.query(QueryBuilders.matchQuery(字段名, 字段值));//关键词
        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(EsConstant.INDEX_LOGIN) //索引库类型,登录档
                .addType(EsConstant.DEFAULT_DOC)   //查所有类型的数据
                .build();
        try {
            // 获取结果
            SearchResult searchResult = jestClient.execute(search);
            // title是ApArticle中的字段,查ApArticle
            List<LogIn> sourceAsObjectList = searchResult.getSourceAsObjectList(LogIn.class);
            // 筛选补充字段数据,获取的数据只有部分字段
            for (LogIn logIn : sourceAsObjectList) {
                // 补全信息
                logIn = logInService.selectOne(logIn);
                if(logIn == null){
                    continue;
                }
                resultList.add(logIn);
            }
            return new ResponseResult<List<LogIn>>(ResponseResult.CodeStatus.OK, "查询成功",resultList);
        } catch (IOException e) {
            e.printStackTrace();
        }
Kibana查看

# 查看所有索引
GET /_cat/indices?v
# 新建索引库
PUT user
DELETE user_login
# 新建映射
PUT user_login
{
  "mappings": {
  	"_doc":{
  		"properties": {
  		  "equipment": {
  			"type": "text",
  			"fields": {
  			  "keyword": {
  				"type": "keyword",
  				"ignore_above": 256
  			  }
  			},
  			"analyzer": "ik_smart"
  		  },
  		  "userId": {
  			"type": "text",
  			"fields": {
  			  "keyword": {
  				"type": "keyword",
  				"ignore_above": 256
  			  }
  			},
  			"analyzer": "ik_smart"
  		  },
  		  "firstId": {
  			"type": "long"
  		  }
  		}
  	}
  }
}
Kibana使用
Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和 Elasticsearch 协作。您可以使用 Kibana 对 Elasticsearch 索引中的数据进行搜索、查看、交互操作。您可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现。
Kibana 可以使大数据通俗易懂。它很简单,基于浏览器的界面便于您快速创建和分享动态数据仪表板来追踪 Elasticsearch 的实时数据变化。
访问http://localhost:5601/app/kibana
选择控制台,创建文章索引
相当于一个库,存放搜索的数据,索引就是表
只是用来查看数据,可视化工具,跟代码无关
kibana添加对应的索引例子:
**ik_smart、ik_max_word是中文拆分词模糊搜索。**争对中文的拆分,数字没用
怎么拆分,详看中文分词器,举个例子:
原文keyword:快乐感恩
ik_max_word:快乐 1 快 2 乐感 3 乐 4 感恩 5 感 6 恩 7
ik_smart:快乐 1 感恩 2
PUT app_info_article//索引名
{
  "mappings": {
  	"_doc":{
  		"properties": {
  		  "channelId": {
  			"type": "long"
  		  },
  		  "content": {
  			"type": "text",
  			"fields": {
  			  "keyword": {
  				"type": "keyword",
  				"ignore_above": 256
  			  }
  			},
  			"analyzer": "ik_smart"
  		  },
  		  "id": {
  			"type": "long"
  		  },
  		  "pub_time": {
  			"type": "date"
  		  },
  		  "publishTime": {
  			"type": "date"
  		  },
  		  "query": {
  			"properties": {
  			  "match_all": {
  				"type": "object"
  			  }
  			}
  		  },
  		  "reason": {
  			"type": "text",
  			"fields": {
  			  "keyword": {
  				"type": "keyword",
  				"ignore_above": 256
  			  }
  			}
  		  },
  		  "status": {
  			"type": "long"
  		  },
  		  "tag": {
  			"type": "text",
  			"fields": {
  			  "keyword": {
  				"type": "keyword",
  				"ignore_above": 256
  			  }
  			}
  		  },
  		  "title": {
  			"type": "text",
  			"fields": {
  			  "keyword": {
  				"type": "keyword",
  				"ignore_above": 256
  			  }
  			},
  			"analyzer": "ik_smart"
  		  },
  		  "userId": {
  			"type": "long"
  		  }
  		}
  	}
  }
}
配置索引
要使用Kibana,您必须至少配置一个索引。索引用于标识Elasticsearch索引以运行搜索和分析。它们还用于配置字段。 新建index,就可以在kibana页面查看该索引库的可视化数据。

我们修改索引名称的匹配方式即可,下面2个选项不用勾选。点击create,会展示出当前配置的索引的域信息,如下图:

域的每个标题选项分别代表如下意思:

数据搜索
Discover为数据搜索部分,可以对日志信息进行搜索操作。

可以使用Discover实现数据搜索过滤和搜索条件显示以及关键词搜索,如下图:

DSL语句
Query DSL是一个Java开源框架用于构建类型安全的SQL查询语句。采用API代替传统的拼接字符串来构造查询语句。目前Querydsl支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。elasticsearch提供了一整套基于JSON的查询DSL语言来定义查询。
 Query DSL当作是一系列的抽象的查询表达式树(AST)特定查询能够包含其它的查询,(如 bool ), 有些查询能够包含过滤器(如 constant_score), 还有的可以同时包含查询和过滤器 (如 filtered). 都能够从ES支持查询集合里面选择任意一个查询或者是从过滤器集合里面挑选出任意一个过滤器, 这样的话,我们就可以构造出任意复杂(maybe 非常有趣)的查询了。
索引操作
(1)查询所有索引
GET /_cat/indices?v
结果如下:

(2)删除某个索引
DELETE /名字
效果如下:

(3)新增索引
PUT /名字
效果如下:

(4)创建映射
user库中加了userinfo类型映射,也可以说userinfo是一个索引库。
PUT /user/userinfo/_mapping
{
  "properties": { //变量
    "name":{
      "type": "text",
      "analyzer": "ik_smart",
      "search_analyzer": "ik_smart",
      "store": false
    },
    "city":{
      "type": "text",
      "analyzer": "ik_smart",
      "search_analyzer": "ik_smart",
      "store": false
    },
    "age":{
      "type": "long",
      "store": false
    },
    "description":{
      "type": "text",
      "analyzer": "ik_smart",
      "search_analyzer": "ik_smart",
      "store": false
    }
  }
}
效果如下:

(5)新增文档数据
PUT /user/userinfo/1
{
  "name":"李四",
  "age":22,
  "city":"深圳",
  "description":"李四来自湖北武汉!"
}
效果如下:

(6)修改数据
a.替换操作
更新数据可以使用之前的增加操作,这种操作会将整个数据替换掉,代码如下:
#更新数据,id=4
PUT /user/userinfo/4
{
  "name":"张三丰",
  "description":"在武汉读书,家在武汉!在深圳工作!"
}
效果如下:

使用GET命令查看:
#根据ID查询
GET /user/userinfo/4
效果如下:

b.更新操作
我们先使用下面命令恢复数据:
#恢复文档数据 id=4
PUT /user/userinfo/4
{
  "name":"张三丰",
  "age":66,
  "city":"武汉",
  "description":"在武汉读书,家在武汉!"
}
使用POST更新某个域的数据,域就是列,更新操作是只改对应的域。
#使用POST更新某个域的数据
POST /user/userinfo/4/_update
{
  "doc":{
    "name":"张三丰",
    "description":"在武汉读书,家在武汉!在深圳工作!"
  }
}
效果如下:

使用GET命令查看:
#根据ID查询
GET /user/userinfo/4
效果如下:

(7)删除Document数据
#删除数据
DELETE user/userinfo/7
数据查询
(1)查询所有数据
#查询所有
GET /user/_search
效果如下:

(2)根据ID查询
#根据ID查询
GET /user/userinfo/2
效果如下:

(3)Sort排序
#搜索排序
GET /user/_search
{
  "query":{
    "match_all": {}
  },
  "sort":{
    "age":{
      "order":"desc"
    }
  }
}
效果如下:

(4)分页
#分页实现
GET /user/_search
{
  "query":{
    "match_all": {}
  },
  "sort":{
    "age":{
      "order":"desc"
    }
  },
  "from": 0,
  "size": 2
}
解释:
from:从下N的记录开始查询
size:每页显示条数
效果如下:

过滤查询
(1)term过滤
term主要用于分词精确匹配,如字符串、数值、日期等(不适合情况:1.列中除英文字符外有其它值 2.字符串值中有冒号或中文 3.系统自带属性如_version)
如下案例:
#过滤查询-term
GET _search
{
  "query":{
    "term":{
      "city":"武汉"
    }
  }
}
效果如下:

(2)terms 过滤
terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配 。
案例如下:
#过滤查询-terms 允许多个Term
GET _search
{
  "query":{
    "terms":{
      "city":
        [
          "武汉",
          "广州"
        ]
    }
  }
}
结果如下:

(3) range 过滤
range过滤允许我们按照指定范围查找一批数据。例如我们查询年龄范围
案例如下:
#过滤-range 范围过滤
#gt表示> gte表示=>
#lt表示< lte表示<=
GET _search
{
  "query":{
    "range": {
      "age": {
        "gte": 30,
        "lte": 57
      }
    }
  }
}
上图效果如下:

(4)exists过滤
exists 过滤可以用于查找拥有某个域的数据
案例如下:
#过滤搜索 exists:是指包含某个域的数据检索
GET _search
{
  "query": {
    "exists":{
      "field":"address"
    }
  }
}
效果如下:

(5) bool 过滤
bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:
- must : 多个查询条件的完全匹配,相当于 and。
- must_not : 多个查询条件的相反匹配,相当于 not。
- should : 至少有一个查询条件匹配, 相当于 or。
这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:
案例如下:
#过滤搜索 bool 
#must : 多个查询条件的完全匹配,相当于 and。
#must_not : 多个查询条件的相反匹配,相当于 not。
#should : 至少有一个查询条件匹配, 相当于 or。
GET _search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "city": {
              "value": "深圳"
            }
          }
        },
        {
          "range":{
            "age":{
              "gte":20,
              "lte":99
            }
          }
        }
      ]
    }
  }
}
效果如下:

(6) match_all 查询
可以查询到所有文档,是没有查询条件下的默认语句。
案例如下:
#查询所有 match_all
GET _search
{
  "query": {
    "match_all": {}
  }
}
(7) match 查询
match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。
如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析match一下查询字符:
案例如下:
#字符串匹配
GET _search
{
  "query": {
    "match": {
      "description": "武汉"
    }
  }
}
效果如下:

(8)prefix 查询
以什么字符开头的,可以更简单地用 prefix ,例如查询所有以张开始的用户描述
案例如下:
#前缀匹配 prefix
GET _search
{
  "query": {
    "prefix": {
      "name": {
        "value": "赵"
      }
    }
  }
}
效果如下:

(9)multi_match 查询
multi_match查询允许你做match查询的基础上同时搜索多个字段,在多个字段中同时查一个
案例如下:
#多个域匹配搜索
GET _search
{
  "query": {
    "multi_match": {
      "query": "深圳",
      "fields": [
        "city",
        "description"
      ]
    }
  }
}
效果如下:



















