在介绍本章之前,需要先打开安装的Kibana页面, 并打开命令行工具页面:

并且根据上节的介绍,我们需要根据中文搜索,所以需要在建立映射时,指定中文字段的分词器为Ik分词器, 默认为英文分词器,每个中文一个词,需要重建索引,重建映射,首先用命令行执行如下命令:

# 删除索引
DELETE course
# 建立 course索引
PUT course # 给course 指定映射, analyzer属性指定分词器
PUT course/_mapping
{
"properties": {
"name": {
"type": "text",
"analyzer":"ik_max_word"
},
"description": {
"type": "text",
"analyzer":"ik_max_word"
},
"studymodel": {
"type": "keyword"
}
}
} # 保存三个测试文档
POST /course/_doc
{
"name": "Bootstrap开发框架",
"description": "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel": "201001"
}
POST /course/_doc
{
"name": "Java语言",
"description": "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
"studymodel": "201002"
}
POST /course/_doc
{
"name": "Spring框架",
"description": "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel": "201003"
}

1. 常用搜索入门

1.1 搜索全部

命令: GET course/_search

结果:

{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.0,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "P2xaGX0BjGPlWFrZF6_S",
"_score" : 1.0,
"_source" : {
"name" : "Java语言",
"description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
"studymodel" : "201002"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 1.0,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]
}
}

返回结果包括了所有三个文档,放在数组 hits 中。一个搜索默认返回十条结果。

1.2 match 分词匹配搜索

领域特定语言 (DSL), 使用 JSON 构造了一个请求。我们可以像这样查询所有studymodel为 "201003"的文档:

GET course/_search
{
"query": {
"match": {
"description": "框架"
}
}
}

结果:

{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.6502306,
"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 0.6502306,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 0.43878573,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]
}
}

这个请求使用 JSON 构造,最外围包含了一个"query"属性,这是查询语句必须的

内部使用了一个 match 查询, 匹配了description 属性中带有"框架"二字的文档;

原理:

我们知道,在新增文档时,文本类型的字段会根据类型和分词类型进行拆分分词,并将拆出来的词语存到索引词库中,用于匹配,如果匹配到了,再查询此词语对应的文档,这也就是倒排索引

match查询会首先分析查询条件,先将查询条件进行分词(使用和字段一样的分词器,也可以自己指定),然后再查询

在本例中,搜索词为"框架",分出的词也是框架二字;所以查询到了文档中description 字段带有"框架"二字的文档

匹配多个词语:

GET course/_search
{
"query": {
"match": {
"description": "框架界面"
}
}
}

可以看到,这次搜索的词语,不再是单个词语,而是由"框架" 和 "界面" 两词组成,而搜索时,也会将此搜索语句拆分成这两个词,进行匹配:

结果:

{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.6398609,
"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.6398609,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 0.43878573,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]
}
}

从结果中可以看到, 两个文档中都有"框架" 这个词语, 但是只有一个有"界面"这个 词语, 所以可以判断,词语匹配是或者的关系,只要有一个匹配上即可, 但是根据匹配度,匹配度高的排在前面;而一个词语都没有匹配上的则没有被查询出来;

1.2.1 operator 属性

上面的分词匹配中,我们发现只要文档中匹配到分词中的其中一个词语就算是匹配上了

这是因为默认的match匹配的operator 属性为 or ,即为或者的关系,也可以修改为and 即,每个词语都必须匹配上:

GET course/_search
{
"query": {
"match": {
"description": {
"query": "框架界面",
"operator": "and"
}
}
}
}

结果:

{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.6398609,
"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.6398609,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
}
]
}
}

同样是搜索这个词语,但是匹配到结果就只有这一个每个词语都匹配上的文档

1.2.2 minimum_should_match 属性

上边使用的operator = or表示只要有一个词匹配上就得分,如果实现三个词至少有两个词匹配如何实现?

使用minimum_should_match可以指定文档匹配词的占比

比如搜索语句如下:

GET course/_search
{
"query": {
"match": {
"description": {
"query": "推出框架界面",
"operator": "or",
"minimum_should_match": "80%"
}
}
}
}

结果:

  "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 2.629491,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
}
]

“推出框架界面”会被分为三个词:推出、框架、界面

设置"minimum_should_match": "80%"表示,三个词在文档的匹配占比为80%,即3*0.8=2.4,向下取整得2,表

示至少有两个词在文档中要匹配成功。

1.3 multi Query 匹配多字段

上边学习的matchQuery 一次只能匹配一个Field,本节学习multiQuery,一次可以匹配多个字段。

GET course/_search
{
"query": {
"multi_match": {
"query": "推出框架界面",
"fields":["name","description"],
"operator": "or",
"minimum_should_match": "50%"
}
}
}

指定匹配name, 和description 两个字段, 定义的 operatorminimum_should_match 属性会作用于每个字段的匹配, 只要有一个字段符合条件,则整个表达式成立:

结果:

"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 2.629491,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 0.49917626,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]

结果查询了两个结果,

第一个结果的 namedescription 属性都符合 50% 的匹配条件.

第二个结果的 name 属性匹配上"框架字符",50%,向下取整也就是一个词,也算匹配上

1.4 term 精确匹配搜索

Term Query为精确查询,在搜索时会整体匹配关键字,不再将关键字分词。

同样,我们使用 term语句查询 "框架界面" 二字, 将不再匹配到任何文档:

GET course/_search
{
"query": {
"term": {
"description": "框架界面"
}
}
}

结果:

{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}

这就是因为,在使用term搜索时,将不会再对搜索词进行分词,而是进行精确匹配,而原文并没有将 "框架界面"分成一个单独的词语放进索引库中.

所以一般使用term查询,都是为了精确查询,例如:

GET course/_search
{
"query": {
"term": {
"studymodel": "201003"
}
}
}

查询编号为2001003的课程,结果:

 "hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.9808291,
"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 0.9808291,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]

或者可以使用terms ,匹配多个

GET course/_search
{
"query": {
"terms": {
"studymodel": ["201003","201001"]
}
}
}

结果:


"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.0,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 1.0,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]

1.4 模糊匹配

wildcard 通配符查询也是一种底层基于词的查询,它使用标准的 shell 通配符查询: ? 匹配任意字符, * 匹配 0 或多个字符。类似 SQL中的like查询

GET course/_search
{
"query": {
"wildcard": {
"studymodel": "201*"
}
}
}

查询所有编号以"201" 开头的课程,结果将查询出全部:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.0,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "P2xaGX0BjGPlWFrZF6_S",
"_score" : 1.0,
"_source" : {
"name" : "Java语言",
"description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
"studymodel" : "201002"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 1.0,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]

如果有更加复杂的模糊匹配需求,也可以使用正则匹配的方式:

GET course/_search
{
"query": {
"regexp": {
"studymodel": "201[0-9].3+"
}
}
}

匹配以201开头,尾号是3,并且全由数字组成的编号课程,查询结果如下:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 1.0,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]

注意:

wildcardregexp 查询的工作方式需要扫描倒排索引中的词列表才能找到所有匹配的词,然后依次获取每个词相关的文档 ID ,相对比较耗费资源和时间

这也意味着需要同样注意前缀查询存在的问题,对有很多唯一词的字段执行这些查询可能会消耗非常多的资源,所以要避免使用左通配这样的模式匹配(如: *foo.*foo 这样的正则式)

wildcardregexp 查询是基于词操作的,如果用它们来查询 analyzed 字段,它们会检查字段里面的每个词,而不是将字段作为整体来处理。

比方说包含 “Quick brown fox” 的 title 字段会生成词: quickbrownfox

会匹配以下这个查询:

{ "regexp": { "title": "br.*" }}

但是不会匹配以下两个查询:

{ "regexp": { "title": "Qu.*" }}
{ "regexp": { "title": "quick br*" }}

在索引里的词是 quick 而不是 Quick

quickbrown 在词表中是分开的。

1.5 布尔查询

布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。类似SQL中的 or 或者 and

三个参数:

​ must:文档必须匹配must所包括的查询条件,相当于 “AND”

​ should:文档应该匹配should所包括的查询条件其当于 "OR"

​ must_not:文档不能匹配must_not所包括的该查询条件,相当于“NOT”

分别使用 must、should、must_not测试下边的查询:

1.5.1 must

GET course/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"description": "程序"
}
},
{
"match": {
"name": "框架"
}
}
]
}
}
}

如表达式所示, 使用了bool 表达式包含了两个match查询(子查询类型无所谓,bool查询只是对各个结果取最终结果)

需要同时满足 descriptionname 字段都匹配上对应的字符

结果只有一条满足:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.777754,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
}
]

1.5.2: should

GET course/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"description": "程序"
}
},
{
"match": {
"name": "框架"
}
}
]
}
}
}

两个表达式,只要一个满足即可

结果匹配了两个满足条件的:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.777754,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : 0.49917626,
"_source" : {
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益",
"studymodel" : "201003"
}
}
]

同时这里也可以使用"minimum_should_match" 属性,来自定义需要匹配的条数,默认相当于1, 即表达式中满足一条结果即可,如果设置为2,则代表都需满足,和must相当:

GET course/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"description": "程序"
}
},
{
"match": {
"name": "框架"
}
}
]
, "minimum_should_match": 2
}
}
}

结果:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.777754,
"_source" : {
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果",
"studymodel" : "201001"
}
}
]

1.5.3 must_not

相当于should 表达式的取反,即表达式一个都不能匹配上:

GET course/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"description": "程序"
}
},
{
"match": {
"name": "框架"
}
}
]
}
}
}

结果为name不包含程序二字的并且描述中不包含框架二字的:

"hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "P2xaGX0BjGPlWFrZF6_S",
"_score" : 0.0,
"_source" : {
"name" : "Java语言",
"description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征",
"studymodel" : "201002"
}
}
]

1.6 范围查询

在介绍后面之前,需要添加一个数值类型的价格字段,执行如下命令:

# 添加字段,指定类型为float
PUT course/_mapping
{
"properties": {
"price": {
"type": "float"
}
}
}
#根据编号修改价格:
POST course/_update_by_query
{
"script": {
"source": "ctx._source['price']=10.5;"
},
"query":{
"term": {
"studymodel": {
"value": "201001"
}
}
}
} POST course/_update_by_query
{
"script": {
"source": "ctx._source['price']=5.6;"
},
"query":{
"term": {
"studymodel": {
"value": "201002"
}
}
}
} POST course/_update_by_query
{
"script": {
"source": "ctx._source['price']=20.3;"
},
"query":{
"term": {
"studymodel": {
"value": "201003"
}
}
}
}

对于数字,除了精确值查询。实际上,对进行过滤有时会更有用。例如,我们可能想要查找所有价格大于 10 且小于 20 元的课程。可以使用 range查询:

GET course/_search
{
"query": {
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
}

查询结果:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 1.0,
"_source" : {
"price" : 10.5,
"studymodel" : "201001",
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
}
}
]

range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:

  • gt: > 大于(greater than)
  • lt: < 小于(less than)
  • gte: >= 大于或等于(greater than or equal to)
  • lte: <= 小于或等于(less than or equal to)

2. 排序

在使用query关键字搜索时,默认按照每个文档的得分,也就是文档对于搜索条件的匹配度进行排序(_score字段)

也可以指定结果排序,这样在查询时,将不会进行计算得分

下面根据价格查询5~30的课程,并按价格降序

GET course/_search
{
"query": {
"range": {
"price": {
"gte": 5,
"lte": 30
}
}
}
, "sort": [
{
"price": {
"order": "asc"
}
}
]
}

结果:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "P2xaGX0BjGPlWFrZF6_S",
"_score" : null,
"_source" : {
"price" : 5.6,
"studymodel" : "201002",
"name" : "Java语言",
"description" : "Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征"
},
"sort" : [
5.6
]
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : null,
"_source" : {
"price" : 10.5,
"studymodel" : "201001",
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
},
"sort" : [
10.5
]
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : null,
"_source" : {
"price" : 20.3,
"studymodel" : "201003",
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益"
},
"sort" : [
20.3
]
}
]

如果需要按照多个字段排序,类似mysql, 也可以指定多个字段,如果第一个字段相同,则按第二个字段排序:

GET course/_search
{
"query": {
"range": {
"price": {
"gte": 5,
"lte": 30
}
}
}
, "sort": [
{
"price": {
"order": "asc"
}
},
{
"studymodel": {
"order": "asc"
}
}
]
}

3. 分页

ES支持分页查询,传入两个参数:from和size。和mysql中的limit 两个参数相同

form:表示起始文档的下标,从0开始。

size:查询的文档数量。

下面排序后,从下标1开始查询,查询两个


GET course/_search
{
"query": {
"range": {
"price": {
"gte": 5,
"lte": 30
}
}
},
"from":1,
"size":2
, "sort": [
{
"price": {
"order": "asc"
}
},
{
"studymodel": {
"order": "asc"
}
}
]
}

结果并没有显示第一条价格最低的商品

  "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : null,
"_source" : {
"price" : 10.5,
"studymodel" : "201001",
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
},
"sort" : [
10.5,
"201001"
]
},
{
"_index" : "course",
"_type" : "_doc",
"_id" : "QGxjGX0BjGPlWFrZka88",
"_score" : null,
"_source" : {
"price" : 20.3,
"studymodel" : "201003",
"name" : "Spring框架",
"description" : "Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益"
},
"sort" : [
20.3,
"201003"
]
}
]

4. 过滤器(filter)

Elasticsearch 使用的查询语言(DSL)拥有一套查询组件,这些组件可以以无限组合的方式进行搭配。

这套组件可以在以下两种情况下使用:过滤情况(filtering context)和查询情况(query context)。

当使用于 过滤情况(filter) 时,查询被设置成一个“不评分”或者“过滤”查询。即,这个查询只是简单的问一个问题:“这篇文档是否匹配?”。回答也是非常的简单,yes 或者 no ,二者必居其一。

  • created 时间是否在 20132014 这个区间?
  • status 字段是否包含 published 这个单词?
  • lat_lon 字段表示的位置是否在指定点的 10km 范围内?

当使用于 查询情况(query) 时,查询就变成了一个“评分”的查询。和不评分的查询类似,也要去判断这个文档是否匹配,同时它还需要判断这个文档匹配的有 多好(匹配程度如何)。 此查询的典型用法是用于查找以下文档:

  • 查找与 full text search 这个词语最佳匹配的文档
  • 包含 run 这个词,也能匹配 runsrunningjog 或者 sprint
  • 包含 quickbrownfox 这几个词 — 词之间离的越近,文档相关性越高
  • 标有 lucenesearch 或者 java 标签 — 标签越多,相关性越高

性能差异:

过滤查询(filter)只是简单的检查包含或者排除,这就使得计算起来非常快。并且结果会被缓存到内存中

以便快速读取,所以有各种各样的手段来优化查询结果。

相反,评分查询(query)不仅仅要找出匹配的文档,还要计算每个匹配文档的相关性,计算相关性使得它们比不评分查询费力的多。同时,查询结果并不缓存。

多亏倒排索引,一个简单的评分查询在匹配少量文档时可能与一个涵盖百万文档的filter表现的一样好,甚至会更好。但是在一般情况下,一个filter 会比一个评分的query性能更优异,并且每次都表现的很稳定。

通常的规则是,使用查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分 的搜索。除此以外的情况都使用过滤(filters)。

使用:

自 Elasticsearch 问世以来,查询与过滤(queries and filters)就独自成为 Elasticsearch 的组件。

但从 Elasticsearch 2.0 开始,过滤(filters)已经从技术上被排除了, 我们上面所有的查询也是基于query关键字,进行查询, 但是,在bool查询中,我们可以使用 除了must,shuold,must_not 之外的属性filter,来实现

如下例, 匹配description 字段,并且使用过滤(filter)的方式再匹配studymodel和price 字段,其中filter的含义和must相同,代表filter里的所有条件都需要满足

GET course/_search
{
"query": {
"bool": {
"must": [{
"match": {
"description": {
"query": "框架"
}
}
}],
"filter": [{
"term": {
"studymodel": "201001"
}
},
{
"range": {
"price": {
"gte": 5,
"lte": 20
}
}
}
]
} }
}

结果:

    "hits" : [
{
"_index" : "course",
"_type" : "_doc",
"_id" : "PmxaGX0BjGPlWFrZEK_N",
"_score" : 0.6502306,
"_source" : {
"price" : 10.5,
"studymodel" : "201001",
"name" : "Bootstrap开发框架",
"description" : "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现一个不受浏览器限制的精美界面效果"
}
}
]

ElasticSearch基本查询使用(2)的更多相关文章

  1. 【转】elasticsearch的查询器query与过滤器filter的区别

    很多刚学elasticsearch的人对于查询方面很是苦恼,说实话es的查询语法真心不简单-  当然你如果入门之后,会发现elasticsearch的rest api设计是多么有意思. 说正题,ela ...

  2. 基于百度地图SDK和Elasticsearch GEO查询的地理围栏分析系统(1)

    本文描述了一个系统,功能是评价和抽象地理围栏(Geo-fencing),以及监控和分析核心地理围栏中业务的表现. 技术栈:Spring-JQuery-百度地图WEB SDK 存储:Hive-Elast ...

  3. Elasticsearch Kibana查询语法

    Elasticsearch Kibana查询语法 2018年06月03日 23:52:30 wangpei1949 阅读数:3992   Elasticsearch Kibana Discover的搜 ...

  4. ElasticSearch—分页查询

    ElasticSearch查询—分页查询详解 Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回.那么,如何实现分页查询呢? 按照一般的查询流程来说,如 ...

  5. Elasticsearch 邻近查询示例

    Elasticsearch 邻近查询示例(全切分分词) JAVA API方式: SpanNearQueryBuilder span = QueryBuilders.spanNearQuery(); s ...

  6. elasticsearch简单查询

    elasticsearch简单查询示例: { "from": "0", //分页,从第一页开始 "size": "10" ...

  7. ElasticSearch高级查询

    ElasticSearch高级查询 https://www.imooc.com/video/15759/0 ElasticSearch查询 1,子条件查询:特定字段查询所指特定值 1.1query c ...

  8. elasticsearch 分页查询实现方案——Top K+归并排序

    elasticsearch 分页查询实现方案 1. from+size 实现分页 from表示从第几行开始,size表示查询多少条文档.from默认为0,size默认为10,注意:size的大小不能超 ...

  9. ELK 学习笔记之 elasticsearch 基本查询

    elasticsearch 基本查询: 基本查询: term查询: terms查询: from和size查询: match查询: match_all查询: match_phrase查询: multi_ ...

  10. ElasticSearch 常用查询语句

    为了演示不同类型的 ElasticSearch 的查询,我们将使用书文档信息的集合(有以下字段:title(标题), authors(作者), summary(摘要), publish_date(发布 ...

随机推荐

  1. vue中v-model修饰符的使用和组件使用v-model

    1.lazy 修饰器 lazy修饰器在input框中的表现效果是: 当你失去焦点后值才会跟新. 它的跟新时机是失去焦点后 这个修饰器在项目中运用的场景较少 <template> <d ...

  2. LeetCode贪心算法习题讲解

    实验室的算法课程,今天轮到我给师弟师妹们讲贪心算法,顺便也复习一下. 贪心算法这个名字听起来唬人,其实通常是比较简单的.虽然通常贪心算法的实现非常容易,但是,一个问题是否能够使用贪心算法,是一定要小心 ...

  3. 【五】强化学习之Sarsa、Qlearing详细讲解----PaddlePaddlle【PARL】框架{飞桨}

    相关文章: [一]飞桨paddle[GPU.CPU]安装以及环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简 ...

  4. 教你用JavaScript实现调皮的字母

    案例介绍 欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用JavaScript编程实战案例,制作提高打字速度的小游戏-调皮的字母.点击与屏幕上字母相对应的按键,若按键与出现的字母一致 ...

  5. strobe

    总是喜欢一个人出神,置身的场景经常是小时有趣的明晃晃的下午.也不知道为什么印象中有趣的下午的阳光总是让人睁不开眼,我也曾试图给大脑传递过"能不能将那晃眼的阳光删去",但再次置身仍是 ...

  6. Linux shell 判断变量是否包含某个字符串的几种方法

    方法一:利用grep查找 strA="long string" strB="string" result=$(echo $strA | grep "$ ...

  7. Python Rich:美化终端显示效果

    Rich库的功能就像它的名字一样,使Python编程更加丰富(rich),它帮助开发者在控制台(命令行)输出中创建丰富.多彩和具有格式化的文本. 本篇总结了如何使用Rich库让我们的命令行工具更加美观 ...

  8. SQLServer复制表及数据的两种方法

    1.新表不存在(即复制数据的同时创建与旧表相同结构的新表):     select [col1,col2,col3...] into new_table from old_table where 1= ...

  9. NC16527 [NOIP2013]货车运输

    题目链接 题目 题目描述 A 国有 n 座城市,编号从 1 到 n ,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆 ...

  10. 【Unity3D】发射(Raycast)物理射线(Ray)

    1 前言 ​ 碰撞体组件Collider 中介绍了 2 个碰撞体之间的碰撞检测,本文将介绍物理射线与碰撞体之间的碰撞检测.物理射线由 Ray 定义,通过 Physics.Raycast / Physi ...