ES与RDBMS数据库比较
简单对比
RDBMS | Elasticsearch | 备注 |
---|---|---|
Database(数据库) | Index(索引) | |
Table(表) | Type(类型) | ES6.x后一个index对应一个type |
Row(行) | Docment(文档) | es保存json |
Column(列) | Field(字段) | |
Schema(约束) | Mapping(映射) | 只能说类似,不完全一样 |
Index(所以) | Everything is indexed(万物皆为索引) | es中存储数据都是索引 |
SQL(结构化查询语言) | DSL(ES独特的查询语言) |
索引
1、结构化索引
针对字段类型: 日期、时间、数字类型,以及精确的文本匹配。
结构化检索特点:
- 结构化查询,我们得到的结果 总是 非是即否,要么存于集合之中,要么存在集合之外。
- 结构化查询不关心文件的相关度或评分;它简单的对文档包括或排除处理。
1.1 精确值查找
1.1.1 单个精确值查找(term query)
term 查询是简单查询,接受一个字段名和参数,进行精准查询,类似sql中:
select * from logs where level ='INFO'
ES中对应的DSL如下:
GET logstash-logs-api-2019.03/_search
{
"query": {
"term": {
"level": {
"value": "INFO"
}
}
}
}
1.1.2 字符串类型精确查询
在ES5.x及以上版本,字符串类型需设置为keyword或text类型,根据类型来进行精确值匹配。
当进行精确值查询,可以使用过滤器,因为过滤器的执行非常快,不会计算相关度(ES会计算查询评分),且过滤器查询结果容易被缓存。
GET test_index/user/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"school": "world"
}
},
"boost": 1.2
}
}
}
1.1.3 布尔过滤器
bool过滤器组成部分:
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
"filter": []
}
}
- must 所有的语句都 必须(must) 匹配,与 AND 等价。
- must_not 所有的语句都 不能(must not) 匹配,与 NOT 等价。
- should 至少有一个语句要匹配,与 OR 等价。
- filter 必须匹配,运行在非评分&过滤模式。
当我们需要多个过滤器时,只须将它们置入 bool 过滤器的不同部分即可。
1.1.4 多值精确查询(terms query)
terms是包含的意思,如下:
GET test_index/_search
{
"query": {
"terms": {
"name": [
"奥尼尔",
"麦迪"
]
}
}
}
name包含["奥尼尔","麦迪"]
返回结果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "test_index",
"_type": "user",
"_id": "9lrZpGkBcbRJikqNMPkF",
"_score": 1,
"_source": {
"name": "奥尼尔"
}
},
{
"_index": "test_index",
"_type": "user",
"_id": "91rZpGkBcbRJikqNNPm5",
"_score": 1,
"_source": {
"name": "麦迪"
}
}
]
}
}
1.2 范围检索(range query)
range查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:
gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)
类似sql中的范围查询:
SELECT document FROM test_index WHERE age BETWEEN 10 AND 30
ES中对应的DSL如下:
GET test_index/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"age": {
"gte": 10,
"lte": 30
}
}
}
]
}
}
}
1.3 存在与否检索(exist query)
如下sql,age不为null:
SELECT * FROM test_index WHERE age IS NOT NULL
ES中对应的DSL如下:
GET test_index/_search
{
"query": {
"bool": {
"must": {
"exists": {
"field": "age"
}
}
}
}
}
如下sql,age为null:
SELECT * FROM test_index WHERE age IS NULL
ES中对应的DSL如下:
GET test_index/_search
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "age"
}
}
}
}
}
注:missing查询在5.x版本已经不存在。
1.4 前缀检索(Prefix Query)
匹配包含 not analyzed(未分词分析)的前缀字符:
GET test_index/_search
{
"query": {
"prefix": {
"name": {
"value": "奥"
}
}
}
}
1.5 通配符检索( Wildcard Query)
匹配具有匹配通配符表达式( (not analyzed )的字段的文档。 支持的通配符:
1)* 它匹配任何字符序列(包括空字符序列);
2)? 它匹配任何单个字符。
请注意,此查询可能很慢,因为它需要遍历多个术语。
为了防止非常慢的通配符查询,通配符不能以任何一个通配符*****或?开头。
GET test_index/_search
{
"query": {
"wildcard": {
"name": {
"value": "奥*"
}
}
}
}
1.6 正则表达式检索(Regexp Query)
正则表达式查询允许您使用正则表达式术语查询。
举例如下:
GET /_search
{
"query": {
"regexp":{
"name.first": "s.*y"
}
}
}
注意: *的匹配会非常慢,你需要使用一个长的前缀,
通常类似.*?+通配符查询的正则检索性能会非常低。
1.7 模糊检索(Fuzzy Query)
模糊查询查找在模糊度中指定的最大编辑距离内的所有可能的匹配项,然后检查术语字典,以找出在索引中实际存在待检索的关键词。
GET test_index/_search
{
"query": {
"fuzzy": {
"name": {"value": "奥尼尔"}
}
}
}
1.8 类型检索(Type Query)
举例:
GET test_index/_search
{
"query": {
"type":{
"value":"user"
}
}
}
检索索引test_index中,type为user的全部信息。不过在es6.x版本,一个index仅有一个type,未来es7.x版本,将取消type,所以这个查询没啥意义。
1.9 Ids检索(Ids Query)
返回指定id的全部信息。
GET test_index/_search
{
"query": {
"ids": {
"values": ["-FresmkBcbRJikqNGfkf","-VresmkBcbRJikqNQfli"]
}
}
}
2、全文检索
全文检索查询,是通过分析器,对查询条件进行分析,然后在全文本字段进行全文查询。
全文搜索取决于mapping中设定的analyzer(分析器),这里使用的是ik分词器。
所以在进行查询开发时候,需要先了解index的mapping,从而选择查询方式。
2.1 匹配检索(Match Query)
匹配查询接受文本/数字/日期类型,分析它们,并构造查询。
对查询传入参数进行分词,搜索词语相同文档。
GET logstash-productspus/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"ProductOriginalName": "激光"
}
}
]
}
}
}
2.2 匹配短语检索(Match_Phrase Query)
match_phrase查询分析文本,并从分析文本中创建短语查询。
GET logstash-productspus/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase": {
"ProductOriginalName": "激光"
}
}
]
}
}
}
2.3 匹配解析前缀检索(Match_Phrase_Prefix)
用户已经渐渐习惯在输完查询内容之前,就能为他们展现搜索结果,这就是所谓的即时搜索(instant search) 或输入即搜索(search-as-you-type) 。
不仅用户能在更短的时间内得到搜索结果,我们也能引导用户搜索索引中真实存在的结果。
例如,如果用户输入 johnnie walker bl ,我们希望在它们完成输入搜索条件前就能得到: Johnnie Walker Black Label 和 Johnnie Walker Blue Label 。
match_phrase_prefix与match_phrase相同,除了它允许文本中最后一个术语的前缀匹配。
GET logstash-productspus/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase_prefix": {
"ProductOriginalName": "WJD"
}
}
]
}
}
}