ES中常用的查询类型往大了分可以分为简单查询,复合查询,聚合查询等;
而复合查询及聚合查询都是基于简单查询的;简单查询里面对条件的匹配方式又分为不同类型。term[s],match,match_all,match_phrase 等等
单词查询,在字段的倒排索引(发生分词)或者直接在字段值(未发生分词)中查找条件值,只要找到这个条件值就算匹配上,得分为1。
多个单词查询,效果为 多个 term 或者的逻辑。bool -> should -> term1,term2…
一般用于对数值类型进行范围查询
无条件查询,匹配所有数据
GET /stu/_search
{
"query": {
"match": {
"name": {
"query": "张 四",
"operator": "and"
}
}
}
}
以上查询 operator 默认为 or,分词 得到 张 和 四 两个词;对于match 分词后的查询;
and 是必须包含条件分词后所有的单词
or 是只需包含条件分词后任意一个单词。
and 下相对来说精度问题还好点,毕竟要包含所有条件分词单词。
如果是在or的情况,我们想要定义至少包含几个单词才当作匹配上,此时还需要另一个参数 minimum_should_match 。
虽然在and情况下,用得相对较少,但对and也有效
此值也可以设置为百分比,意思是条件分词后,达到比例的条件单词匹配上才算匹配,
比如,以下查询语句是查不出数据的
GET /stu/_search
{
"query": {
"match": {
"name": {
"query": "张 四",
"operator": "and",
"minimum_should_match": 3
}
}
}
}
因为你的条件分词,只有 2个词,即使分词也只得到2个词, 小于 minimum_should_match
以当前条件值,到文档**字段(而非分词后的列表)**里查询。
条件不做分词,到文档字段内 进行连续的 文本匹配
同样是以 条件不做分词到文档字段中查询,但是条件最后的 单词不是必须匹配字段内的完整单词
例如:
文档字段为 i love you
条件为 i love yo
match_phrase 下 无法匹配,因为 文档中 you 是一个完整的单词;只能匹配 i 或者 i love 或者 i love you
match_pharse_prefix 就可以匹配,就是说只要是一个前缀包含的连续文本就能匹配
条件进行分词,执行 bool > should 查询
前面的词 做 term 查询,最后一个词做 perfix 查询
在实际开发中,特别是模糊查询场景,可能需要将条件应用到多个文档字段上进行匹配。
当然我们可以使用 bool + should 的方式实现。
但ES已经给我们提供了一种更为便捷的方式。
同时匹配 品牌或名称 有苹果的数据
"query": {
"multi_match" : {
"query": "苹果",
"fields": [ "brand", "name" ]
}
}
等价于
"query": {
"bool": {
"should": [
{
"match": {
"brand": "苹果"
}
},
{
"match": {
"name": "苹果"
}
}
]
}
}
以下是引用自ES社区博客中的一段描述
该查询使用语法基于 OR,AND 或 NOT 等运算符来解析和拆分提供的查询字符串。 然后查询在返回匹配文档之前独立分析每个拆分文本。
你可以使用 query_string 查询创建一个复杂的搜索,其中包括通配符,跨多个字段的搜索等等。 尽管用途广泛,但查询是严格的,如果查询字符串包含任何无效语法,则返回错误。
简单总结:这是使用字符串通过 AND OR NOT 构建复杂查询的一种实现方式,但是语法较严格,容易出错,并不推荐在日常查询中使用
实际测试下来,单个条件执行的应该是match操作
default_field:条件字段,只能一个。
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "address",
"query": "School Lane"
}
}
}
返回结果为 School Lane 的match查询,凡是 address 包含 School 或者 Lane 的都匹配上
上面的简单查询 通过 “default_field”: “字段名” 指定一个查询字段。
当要将条件应用到多个字段时,可以使用 “fields”: [“字段1”, “字段2”],
GET /bank/_search
{
"query": {
"query_string": {
"fields": ["age", "account_number"],
"query": "26"
}
}
}
查询 age match 26 或者 account_number match 26 的数据
在所有字段上执行match操作,只要任何一个字段匹配上就算匹配。
我们只需要去掉 fields 字段即可
GET /bank/_search
{
"query": {
"query_string": {
"query": "28"
}
},
"size": 2000
}
以上,在所有字段上应用 match 28。
在 bank 这个索引下,查到了 age = 28 和 id = 28 的数据
GET /bank/_search
{
"query": {
"query_string": {
"query": "28 OR 30"
}
},
"size": 2000
}
指定字段 fields 或默认字段 default_field都适用这个逻辑关系
NOT 关键字可以用在逻辑关系中任一项的前面,表示查询相反条件
上面指定字段要么使用 fields ,要么使用 default_field,其实还有另一种更为灵活的方式,我们可以直接将字段写到 query查询语句中,
使用 query:“字段名: 条件值” 的方式灵活定制查询条件
GET /bank/_search
{
"query": {
"query_string": {
"query": "age: 30"
}
},
"size": 100
}
GET /bank/_search
{
"query": {
"query_string": {
"query": "age: 30 OR 20"
}
},
"size": 100
}
GET /bank/_search
{
"query": {
"query_string": {
"query": "age: 30 OR account_number:1"
}
},
"size": 100
}
GET /bank/_search
{
"query": {
"query_string": {
"query": "age: (30 OR 20) OR account_number: 1"
}
},
"size": 100
}
如下:
match Sedgwick
GET /bank/_search
{
"query": {
"match": {
"address": "Sedgwick"
}
}
}
match 只能在分词后的倒排索引中精确匹配
如果把条件值改成 Sedgwic,去掉最后一个 k,match就查不出来数据了。
但是使用 query_string 的模糊匹配依然有办法查出来这两条数据
query_string 的模糊匹配有两个通配符
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "address",
"query": "Sedgwic?"
}
}
}
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "address",
"query": "Sedgwic*"
}
}
}
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "address",
"query": "Sedgwi*"
}
}
}
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "address",
"query": "*dgwi*"
}
}
}
以上都能查出来那两条数据。
默认的匹配方式为 match,其本质就是 等值匹配,只是分不分词的区别,
对于 query 中的 range 查询,query_string 中也有对应实现。
并且 query_string 还支持两种写法
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "age",
"query": "{* TO 20]"
}
}
}
GET /bank/_search
{
"query": {
"query_string": {
"query": "age:{* TO 20]"
}
}
}
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "age",
"query": ">=20"
}
}
}
GET /bank/_search
{
"query": {
"query_string": {
"default_field": "age",
"query": ">=20 AND <30"
}
}
}
GET /bank/_search
{
"query": {
"query_string": {
"query": "age:(>=20 AND <30)"
}
}
}