Elasticsearch中当咱们设置Mapping(分词器、字段类型)完毕后,就能够按照设定的方式导入数据。mysql
有了数据后,咱们就须要对数据进行检索操做。根据实际开发须要,每每咱们须要支持包含但不限于如下类型的检索:
1)精确匹配,相似mysql中的 “=”操做;
2)模糊匹配,相似mysql中的”like %关键词% “查询操做;
3)前缀匹配;
4)通配符匹配;
5)正则表达式匹配;
6)跨索引匹配;
7)提高精读匹配。正则表达式
细数一下,咱们的痛点在于:
1)ES究竟支持哪些检索操做?
2)如何实现ES精确值检索、指定索引检索、全文检索?sql
这些就是本文着重参考ES最新官方文档,针对ES5.X版本探讨的内容。缓存
检索子句的行为取决于查询应用于过滤(filter)上下文仍是查询/分析(query)上下文。app
过滤上下文——对应于结构化检索less
1)核心回答的问题是:“这个文档是否符合这个查询条款?” 2)答案是简单的是或否,不计算分数。 3)过滤器上下文主要用于过滤结构化数据。相似于Mysql中断定某个字段是否存在:
例如: post
a. 时间戳字段:是否属于2015年或2016年?
b. 状态字段:是否设置为“已发布”?性能
常常使用的过滤器将被Elasticsearch**自动缓存,以加快性能**。spa
分析上下文——对应于全文检索
1)核心回答了“本文档与此查询子句是否匹配?”的问题。.net
2)除了决定文档是否匹配以外,查询子句还会计算一个_score,表示文档与其余文档的匹配程度。
综合应用场景以下:
GET /_search { "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ] } } }
以上检索,title中包含”Search”而且content中包含 “Elasticsearch”,status中精确匹配”published”,而且publish_date 大于“2015-01-01”的所有信息。如下,以“脑图”的形式直观展现检索分类:
如下内容的原文须要参考ES官方文档(随着版本变化,后续会有更新)
针对字段类型: 日期、时间、数字类型,以及精确的文本匹配。
结构化检索特色:
* 1)结构化查询,咱们获得的结果 老是 非是即否,要么存于集合之中,要么存在集合以外。
* 2)结构化查询不关心文件的相关度或评分;它简单的对文档包括或排除处理。
term 查询会查找咱们指定的精确值。term 查询是简单的,它接受一个字段名以及咱们但愿查找的数值。
想要相似mysql中以下sql语句的查询操做:
SELECT document FROM products WHERE price = 20;
DSL写法:
GET /my_store/products/_search { "query" : { "term" : { "price" : 20 } } }
当进行精确值查找时, 咱们会使用过滤器(filters)。过滤器很重要,由于它们执行速度很是快,不会计算相关度(直接跳过了整个评分阶段)并且很容易被缓存。以下: 使用 constant_score 查询以非评分模式来执行 term 查询并以一做为统一评分。
GET /my_store/products/_search { "query" : { "constant_score" : { "filter" : { "term" : { "price" : 20 } } } } }
注意:5.xES中,对于字符串类型,要进行精确值匹配。须要讲类型设置为text和keyword两种类型。mapping设置以下:
POST testindex/testtype/_mapping { "testtype ":{ "properties":{ "title":{ "type":"text", "analyzer":"ik_max_word", "search_analyzer":"ik_max_word", "fields":{ "keyword":{ "type":"keyword" } } } } }
一个 bool 过滤器由三部分组成:
{ "bool" : { "must" : [], "should" : [], "must_not" : [], "filter": [] } }
must ——全部的语句都 必须(must) 匹配,与 AND 等价。
must_not ——全部的语句都 不能(must not) 匹配,与 NOT 等价。
should ——至少有一个语句要匹配,与 OR 等价。
filter——必须匹配,运行在非评分&过滤模式。
就这么简单! 当咱们须要多个过滤器时,只须将它们置入 bool 过滤器的不一样部分便可。
举例:
GET /my_store/products/_search { "query" : { "filtered" : { "filter" : { "bool" : { "should" : [ { "term" : {"price" : 20}}, { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} ], "must_not" : { "term" : {"price" : 30} } } } } } }
{ "terms" : { "price" : [20, 30] } }
如上,terms是包含的意思,包含20或者包含30。
以下实现严格意义的精确值检索, tag_count表明必须匹配的次数为1。
GET /my_index/my_type/_search { "query": { "constant_score" : { "filter" : { "bool" : { "must" : [ { "term" : { "tags" : "search" } }, { "term" : { "tag_count" : 1 } } ] } } } } }
range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项以下:
gt: > 大于(greater than) lt: < 小于(less than) gte: >= 大于或等于(greater than or equal to) lte: <= 小于或等于(less than or equal to)
相似Mysql中的范围查询:
SELECT document FROM products WHERE price BETWEEN 20 AND 40
ES中对应的DSL以下:
GET /my_store/products/_search { "query" : { "constant_score" : { "filter" : { "range" : { "price" : { "gte" : 20, "lt" : 40 } } } } } }
mysql中,有以下sql:
SELECT tags FROM posts WHERE tags IS NOT NULL;
ES中,exist查询某个字段是否存在:
GET /my_index/posts/_search { "query" : { "constant_score" : { "filter" : { "exists" : { "field" : "tags" } } } } }
https://blog.csdn.net/laoyang360/article/details/77623013 1.3接着往下面开始