一、Lucene简介
1、简介
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。业界流行的Elasticsearch和Solr都是在Lucene的基础上进行封装,实现了分布式搜索引擎。
Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库
2、作用
Lucene作为一个全文检索引擎,其具有如下突出的优点:
(1)索引文件格式独立于应用平台。Lucene定义了一套以8位字节为基础的索引文件格式,使得兼容系统或者不同平台的应用能够共享建立的索引文件。
(2)在传统全文检索引擎的倒排索引的基础上,实现了分块索引,能够针对新的文件建立小文件索引,提升索引速度。然后通过与原有索引的合并,达到优化的目的。
(3)优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能。
(4)设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式,只需要实现文本分析的接口。
(5)已经默认实现了一套强大的查询引擎,用户无需自己编写代码即可使系统可获得强大的查询能力,Lucene的查询实现中默认实现了布尔操作、模糊查询(Fuzzy Search[11])、分组查询等等。
二、ElasticSearch概念
1、核心概念
(1)集群cluster
顾名思义,代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的
主节点的职责是负责管理集群状态,包括管理分片的状态和副本的状态,以及节点的发现和删除
只需要在同一个网段之内启动多个es节点,就可以自动组成一个集群。默认情况下es会自动发现同一网段内的节点,自动组成集群。
(2)分片shards
shards代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。ES7之前默认一个索引库默认分片是5个,之后默认分片为1个
(3)replicas
代表索引副本,es可以给索引设置副本,副本的作用:一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
默认情况系一个分片有2个副本,也可以在创建索引库的时候指定副本数量,
(4)recovery
代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
(5)gateway
代表es索引的持久化存储方式,es默认是先把索引存放到内存中,当内存达到某个阈值时再持久化到硬盘。当这个es集群关闭再重新启动时就会从gateway中读取索引数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,如Hadoop的HDFS和amazon的s3云存储服务。
(6)discovery.zen
代表es的自动发现节点机制,es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。 不同网段的节点要组成集群, 要禁用自动发现功能:discovery.zen.ping.multicast.enabled: false 指定发现主节点列表:discovery.zen.ping.unicast.hosts: [“192.168.1.3", "192.168.1.4"]
(7)Transport
代表es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(通过插件方式集成)。
(8)settings和mappings
settings用于修改索引库默认配置,如分片数量,副本数量等
Mapping就是对索引库中索引的字段名称及其数据类型进行定义,类似于关系数据库中表建立时要定义字段名及其数据类型那样,(和solr中的schme类似)不过es的mapping比数据库灵活很多,它可以动态添加字段。一般不需要要指定mapping都可以,因为es会自动根据数据格式定义它的类型,如果你需要对某些字段添加特殊属性(如:定义使用其它分词器、是否分词、是否存储等),就必须手动添加mapping
(2)ES和关系型数据库的数据映射
elasticsearch本质上也是储存数据 所以许多概念与关系型数据库类似
这里需要说明的是elasticsearch7.X开始,移除了type这一概念,包括API层面的
(3)ES内置的REST接口如下
三、ElasticSearch使用
1、索引操作
默认创建索引
curl -XPUT 'http://192.168.1.73:9200/xyerp/'
xyerp为建立的索引,0 表示1个分片,分片有1个副本,粗边框的表示主分片,窄边框的表示副本分片
这里需要说明的是索引一旦建立,其主分片数量是不能修改的,只能更改副本分片数量。如果要更改主分片数量,要先删除索引重新建索引。elasticsearch7.x开始默认分片由5个变为1个,可以看到三个节点只有0一个分片。因此在实际使用中,我们创建索引的时候要根据未来业务、设备、数据量合理设置分片数量。
指定分片数3及副本数2
curl -XPUT 'http://192.168.1.73:9200/xyerp2/' -H 'Content-Type: application/json' -d '
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}'
可以看到索引xyerp2有3个分片0、1、2,每个分片有2个副本,粗边框的表示主分片,窄边框的表示副本分片
删除索引
curl -XDELETE 'http://192.168.1.73:9200/xyepr/
2、文档库操作
(1)添加数据,添加五条订单数据
curl -XPOST 'http://192.168.1.73:9200/xyerp/order/' -H 'Content-Type: application/json' -d '
{
"user_id": "xy195110000",
"goods_name":"刀削面",
"order_no": "20191020122735123",
"order_time": "2019-10-20T14:12:11",
"pay_time": "2019-10-20T14:12:12"
}'
curl -XPOST 'http://192.168.1.73:9200/xyerp/order/' -H 'Content-Type: application/json' -d '
{
"user_id": "xy195110000",
"goods_name":"酸辣水饺",
"order_no": "20191020202735003",
"order_time": "2019-10-20T19:10:10",
"pay_time": "2019-10-20T19:10:12"
}'
curl -XPOST 'http://192.168.1.73:9200/xyerp/order/' -H 'Content-Type: application/json' -d '
{
"user_id": "xy195110001",
"goods_name":"营养快线",
"order_no": "20191021202735001",
"order_time": "2019-10-21T19:10:10",
"pay_time": "2019-10-21T19:10:12"
}'
curl -XPOST 'http://192.168.1.73:9200/xyerp/order/' -H 'Content-Type: application/json' -d '
{
"user_id": "xy195110001",
"goods_name":"手撕牛肉",
"order_no": "20191022202735003",
"order_time": "2019-10-22T19:10:10",
"pay_time": "2019-10-22T19:10:12"
}'
curl -XPOST 'http://192.168.1.73:9200/xyerp/order/' -H 'Content-Type: application/json' -d '
{
"user_id": "xy195110001",
"goods_name":"刀削面",
"order_no": "20191022212735003",
"order_time": "2019-10-22T19:10:10",
"pay_time": "2019-10-22T19:10:12"
}'
可以看到添加的5条数据已经进来了
(2)一般查询
根据document的id查询数据
curl -XGET http://192.168.1.73:9200/xyerp/order/Gbuszm0BkjUhrK7OnlOR?pretty
根据field来查询数据
curl -XGET http://192.168.1.73:9200/xyerp/order/_search?q=user_id=xy195110000&pretty=true
或者
curl -XGET http://192.168.1.73:9200/xyerp/order/_search?q=user_id:xy195110000&pretty=true
根据field来查询数据:match
curl -XGET 'http://192.168.1.73:9200/xyerp/_search?pretty=true' -H 'Content-Type: application/json' -d '
{
"query" : {
"match" : { "goods_name": "刀削面" }
}
}'
对多个field发起查询:multi_match,查询goods_name和user_id中包含“刀削面”的字样
curl -XGET http://192.168.1.73:9200/xyerp/order/_search -H 'Content-Type: application/json' -d '
{
"query":
{"multi_match":
{
"query":"刀削面",
"fields":["goods_name","user_id"],
"operator":"or"
}
}
}'
range范围查询
curl -XGET 'http://192.168.1.73:9200/xyerp/_search?pretty=true' -H 'Content-Type: application/json' -d '
{
"query" : {
"range" : {
"order_time" : { "from" : "2019-10-20T00:00:00", "to" : "2019-10-21T00:00:00" }
}
}
}'
(2)复合查询
符合查询主要包括以下查询:bool query
(布尔查询)、boosting query
(提高查询)、constant_score
(固定分数查询)、dis_max
(最佳匹配查询)、function_score
(函数查询)
这里主要说布尔查询,Bool查询语法有以下特点
- 子查询可以任意顺序出现
- 可以嵌套多个查询,包括bool查询
- 如果bool查询中没有must条件,should中必须至少满足一条才会返回结果。
bool查询包含四种操作符,分别是must,should,must_not,query。他们均是一种数组,数组里面是对应的判断条件。
must: 必须匹配。贡献算分
must_not:过滤子句,必须不能匹配,但不贡献算分
should: 选择性匹配,至少满足一条。贡献算分
filter: 过滤子句,必须匹配,但不贡献算分
must交集 同时匹配多个条件
curl -XGET http://192.168.1.73:9200/xyerp/order/_search -H 'Content-Type: application/json' -d '
{
"query":
{"bool" :
{
"must" :
[{"match":
{"goods_name":"刀削面"}
},
{"match":
{"user_id":"xy195110001"}
}
]
}
}
}'
must +must_not 差集,must_not 对must的结果进行过滤
curl -XGET http://192.168.1.73:9200/xyerp/order/_search -H 'Content-Type: application/json' -d '
{
"query":
{"bool" :
{
"must" :
{"term" :
{ "goods_name" : "刀削面" }
}
,
"must_not" :
{"range":
{"order_time" : { "from" : "2019-10-20T00:00:00", "to" : "2019-10-20T23:59:59"}
}
}
}
}
}'
四、Java API操作ElasticSearch
(未完待续)