作为经典的文档检索数据库,ElasticSearch提供了丰富的接口来搜索数据,满足用户不同的搜索需求。我们的系统为了支持实时字段明细查询功能,会将数据实时写入ES。整个系统数据量较多且维度丰富,每天写入的文档数据达到10多亿条,单个最大索引存储达到2T以上,除了满足业务的查询功能需求之外,数据的时效性以及存储空间都是系统必须优化考虑的问题。本文对ES中一些常用的匹配查询方式原理及其在业务系统中的使用场景进行介绍。
匹配查询
ElasticSearch官方对文本查询介绍了两种方式:基于词项和基于全文的查询。
基于词项
基于词项的查询只对倒排索引的词项精确匹配,查询时没有分析阶段,不会对词的多样性进行处理,假若使用“Hello”进行关键词检索时,不会搜索到倒排索引中包含单词“hello”的词条。
典型的基于词项查询我们以term query为具体案例进行介绍:
创建索引数据
在解释查询模式之前,首先创建索引数据,在索引中分别定义exact_value和full_text字段作为keyword和text两种数据类型字符串。
PUT my_index/_mapping/my_type
{
"properties": {
"exact_value": {
"type": "keyword"
},
"full_text": {
"type": "text"
}
}
}
PUT my_index/my_type/1
{
"exact_value": "Hello World!",
"full_text": "Hello World!"
}
索引中keyword和text两种不同的数据类型,我来看看两个字段分别在倒排索引中的创建索引的方式。
Keyword:exact_value字段
{
“tokens”: [
{
“token”: “Hello World!”,
“start_offset”: 0,
“end_offset”: 12,
“type”: “word”,
“position”: 0
}
]
}
Text:full_text字段
{
“tokens”: [
{
“token”: “hello”,
“start_offset”: 0,
“end_offset”: 5,
“type”: “”,
“position”: 0
},
{
“token”: “world”,
“start_offset”: 6,
“end_offset”: 11,
“type”: “”,
“position”: 1
}
]
}
由于keyword类型字段不会经过分析器处理,exact_value在倒排索引中以[Hello Wrold!]的完整形式建立索引;text类型经过分析器处理,分析器会将内容进行字符过滤、分词、大小写转换等操作,full_text字段在倒排索引中拆分为[hello、world]两个单词元素形式建立索引。
Term Query
对上述写入索引的文档,使用term查询方式,我们来看看效果
1、GET my_index/my_type/_search