目录
全文搜索Lucene入门
1.全文搜索概述
1.1.什么是全文检索
1.2.为什么要使用全文搜索
2.Lucene概述
2.1.什么是Lucene
2.2.Lucene索引原理
ElasticSearch相关概念
1.ElasticSearch介绍
1.1.什么是ElasticSearch
1.2.ES和lucene的关系与区别
ES下载和安装
Kibana5安装
ElasticSearch基础概念与CRUD
ES概念与Mysql基本概念对应关系
基本增删查改操作
DSL查询与DSL过滤
1.区别
2.案例
3.查询方式
全匹配(match_all)
match查询
multi_match查询
term查询
ids
term
range
range查询
。。。等
安装IK分词器
IK分词测试
文档类型映射
SpringBootData操作ES
环境集成
配置yml
编写Document对象
创建Repository
创建索引和映射、调用CRUD方法
DSL查询
狭义的理解主要针对文本数据的搜索。数据可分为“结构化”数据(关系数据库表形式管理的数据),半结构化数据(XML文档、JSON文档),和非结构化数据(WORD、PDF),通常而言在结构化的数据中搜索性能是比较高的,全文搜索的目的就是把非结构化的数据变成有结构化的数据进行搜索,从而提高搜索效率。
搜索效率高,是like无法比拟的
相关度最高的排在最前面,官网中相关的网页排在最前面; java
关键词的高亮。
Lucene是apache下的一个开源的全文检索引擎工具包(一堆jar包)。它为软件开发人员提供一个简单易用的工具包(类库),以方便的在小型目标系统中实现全文检索的功能。Lucene适用于中小型项目 ,ES适用于中大型项目(它底层是基于lucene实现的)
参考大佬:Lucene详解_lucene原理_jofjhh的博客-CSDN博客
ES是一个分布式的全文搜索引擎,为了解决原生Lucene使用的不足,优化Lucene的调用方式,并实现了高可用的分布式集群的搜索方案,ES的索引库管理支持依然是基于Apache Lucene(TM)的开源搜索引擎。ES也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API来隐Lucene的复杂性,从而让全文搜索变得简单。
下载地址:Download Elasticsearch | Elastic
ES服务只依赖于JDK,推荐使用JDK1.8+。
测试与安装:解压,双击安装目录 bin/elasticsearch.bat即可启动,使用浏览器访问:http://localhost:9200
启动之后不要选中或点击cmd弹出框,不然后期代码操作时会报错,若已经点击或选中,按右键即可取消。
下载地址:Download Kibana Free | Get Started Now | Elastic
注意需要选择与ES版本对应的Kibanna,不然无法访问。
Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。可以用kibana搜索、查看、交互存放在Elasticsearch索引里的数据,使用各种不同的图表、表格、地图等kibana能够很轻易地展示高级数据分析与可视化。
解压并编辑config/kibana.yml,设置elasticsearch.url的值为已启动的ES
默认情况下,Kibana会链接本地的默认ES http://localhost:9200
,如果需要修改链接的ES服务器,通过修改安装目录下 config/kibana.yml,将配置项 #elasticsearch.url: "http://localhost:9200"
取消注释即可修改连接的ES服务器地址。
ElastciSearch全文搜索 | Mysql关系型数据库 |
---|---|
索引库(index) | 数据库(database) |
文档类型(Type) | 数据表(Table) |
文档(Document) | 一行数据(Row) |
字段(field) | 一个列(column) |
文档ID | 主键ID |
查询(Query DSL) | 查询(SQL) |
GET http://.. | SELECT * FROM ... |
PUT http:// | UPDATE table set... |
参考文章:ES索引的基本操作(CRUD)_es crud_三思呐三思的博客-CSDN博客
DSL查询是由ES提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询
。DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。DSL有两部分组成:DSL查询和DSL过滤。
1 查询上下文中,查询操作不仅仅会进行查询,还会计算分值,用于确定相关度;在过滤器上下文中,查询操作仅判断是否满足查询条件
2 过滤器上下文中,查询的结果可以被缓存。
解释:
query : 查询,所有的查询条件在query里面
bool : 组合搜索bool可以组合多个查询条件为一个查询对象,这里包含了 DSL查询和DSL过滤的条件
must : 必须匹配 :与(must) 或(should) 非(must_not)
match:分词匹配查询,会对查询条件分词 , multi_match :多字段匹配
filter: 过滤条件
term:词元查询,不会对查询条件分词
from,size :分页
_source :查询结果中需要哪些列
sort:排序
查询名称(name)中有 "zs" 的用户 ,性别sex是男生(1),年龄(age)在 18- 20之间,按照年龄(age)倒排序,查询第 1 页,每页10 条 ,查询结果中只需要 :id,name,username,age
GET /crm/user/_search
{
"query":{
"bool": {
"must": [{
"match": {
"name": "zs"
}
}],
"filter": [
{
"range":{ //范围查询
"age":{
"gte":18,
"lte":20
}
}
},
{
"term": { //词元查询
"sex": 1
}
}
]
}
},
"from": 1,
"size": 10,
"_source": ["id", "name", "age","username"],
"sort": [{
"age": "desc"
}]
}
普通搜索(匹配所有文档)
单字段查询
多字段查询,任意一个字段符合条件就算符合查询条件
因为精确查询的字段搜是不分词的字段,因此查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多,反而搜索不到数据。
根据id查询
根据词条精确值查询
根据值的范围查询
范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。
参考文档:【微服务】DSL查询文档_杼蛘的博客-CSDN博客
ES默认对英文文本的分词器支持较好,但和lucene一样,如果需要对中文进行全文检索,那么需要使用中文分词器,同lucene一样,在使用中文全文检索前,需要集成IK分词器。
IK分词器:https://github.com/medcl/elasticsearch-analysis-ik
在ES目录下的plugin中新建一个文件夹,将下载后将分词器的所有文件放到新建的文件夹中。
POST _analyze
{
"analyzer":"ik_smart",
"text":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
运行结果:
参考文档:Elasticsearch(四)--一文弄懂ES的映射操作_es修改映射_雨~旋律的博客-CSDN博客
org.springframework.boot
spring-boot-starter-parent
2.2.5.RELEASE
org.springframework.boot
spring-boot-starter-data-elasticsearch
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
spring:
elasticsearch:
rest:
uris:
- http://localhost:9200
//标记该对象是ES的文档对象
//indexName 索引库
//type 类型
@Document(indexName = "orders",type = "_doc")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderDoc {
//标记为文档ID,该ID的值会作为document的id值
@Id
private Long id;
@Field(type = FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
private String title;
@Field(type = FieldType.Integer)
private Integer count;
@Field(type = FieldType.Integer)
private int status;
@Field(type = FieldType.Double)
private BigDecimal amount;
}
SpringBootData提供了ElasticsearchRepository 来操作ES,该接口中包含了针对ES的CRUD方法
泛型是当前Repository所要管理的实体类,也就是OrderDoc,Long是实体类ID的类型
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ESApplication.class)
public class ESTest {
//操作ES的template模板
@Autowired
private ElasticsearchRestTemplate template;
@Autowired
private OrderRepository orderRepository;
@Test
public void test() {
//创建索引
template.createIndex(OrderDoc.class);
//创建映射
template.putMapping(OrderDoc.class);
}
@Test
public void testAdd() {
for (long i = 0; i < 50; i++) {
OrderDoc orderDoc = new OrderDoc(i,
i % 2 == 0 ? "枇杷" : "苹果",
Integer.valueOf((i % 2 == 0 ? i * 2 : i * 3) + ""),
1,
new BigDecimal(i % 2 == 0 ? i * 2.5 : i * 2.8));
orderRepository.save(orderDoc);
}
}
@Test
public void testGet(){
Optional optional = orderRepository.findById(23l);
System.out.println(optional.get());
}
}
在SpringBoot中我们通过 NativeSearchQueryBuilder 来构建查询条件,调用repository.search来执行查询。
案例:查询标题中包含枇杷 ,数量在50-100之间,金额在10-200之间,按照金额倒排,查询第2页数据,每页10条
@Test
public void testSearch(){
//查询构建器
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
//设置分页: 第2页 (0开始), 每页10数
builder.withPageable(PageRequest.of(1,10));
//设置排序 : 金额倒排
builder.withSort(SortBuilders.fieldSort("amount").order(SortOrder.DESC));
//构建组合查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//标题包含鼠标
boolQuery.must(QueryBuilders.matchQuery("title","枇杷"))
//数量范围查询
.filter(QueryBuilders.rangeQuery("count").gte(50).lte(100))
//金额范围查询
.filter(QueryBuilders.rangeQuery("amount").gte(10).lte(200));
//添加查询条件
builder.withQuery(boolQuery);
//执行搜索
Page page = orderRepository.search(builder.build());
//获取条数
System.out.println("总元素个数:"+page.getTotalElements());
//打印列表
page.getContent().forEach(System.out::print);
}
运行结果: