一 序
本文属于极客时间Elasticsearch核心技术与实战学习笔记系列。
二 结构化数据
结构化搜索(Structured search) 是指对结构化数据的搜索
- 日期,布尔类型和数字都是结构化
文本也可以是结构化的
- 如彩色笔可以有离散的颜色集合:红(red)、绿(green)、蓝(blue)
- 一个博客可能被标记了标签,例如,分布式(distributed)和搜索(search)
- 电商网站上的商品都有 UPCs(通用产品码 Universal Product Codes)或其他的唯一标识,它们都遵从严格规定的、结构化的格式
ES 中的机构化搜索
- 布尔、时间,日期和数字这类结构化数据:有精确的格式,我们可以对这些格式进行逻辑操作。包括比较数字或时间的范围,或判断两个值的大小
- 结构化的文本可以做到精确匹配或者部分匹配
- Term 查询 / Prefix 前缀查询
- 结构化结构只有 “是” 或 “否” 两个值
- 根据场景需要,可以决定结构化搜索是否需要打分
demo
#结构化搜索,精确匹配
DELETE products
POST /products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10,"avaliable":true,"date":"2018-01-01", "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20,"avaliable":true,"date":"2019-01-01", "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30,"avaliable":true, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30,"avaliable":false, "productID" : "QQPX-R-3956-#aD8" }
GET products/_mapping
查询你boolean
查询#对布尔值,通过constant score 转成 filtering,没有算分
数字类型 Term
#数字类型 terms
数字类型支持range查询
constant_score 把filter包起来,并且跳过了算分的步骤
- gt 大于
- lt 小于
- gte 大于等于
- lte 小于等于
日期 range
demo的查询就是大于一年之前的。
exists 查询 - 非空查询
处理多值字段
#处理多值字段
POST /movies/_bulk
{ "index": { "_id": 1 }}
{ "title" : "Father of the Bridge Part II","year":1995, "genre":"Comedy"}
{ "index": { "_id": 2 }}
{ "title" : "Dave","year":1993,"genre":["Comedy","Romance"] }
#处理多值字段,term 查询是包含,而不是等于
POST movies/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"genre.keyword": "Comedy"
}
}
}
}
}
处理多值字段,term 查询是包含,而不是等于
尽管包含除了Comedy以外的其他词,它还是被匹配并作为结果返回
怎么实现genre里面只有Comedy这1个值的搜索结果?
最好的方式是增加并索引另一个字段, 这个字段用以存储该字段包含词项的数量.
我另外插入测试数据
POST /movies/_bulk
{ "index": { "_id": 3 }}
{ "title" : "Father of the Bridge Part II","year":1995, "genre":"Comedy","genre_count" : 1}
{ "index": { "_id": 4 }}
{ "title" : "Dave","year":1993,"genre":["Comedy","Romance"],"genre_count" : 2 }
GET /movies/_doc/3
#处理多值字段,term 查询是包含,而不是等于
POST movies/_search
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must":[
{ "term" : { "genre.keyword" : "Comedy" }},
{ "term" : { "genre_count" : 1 } }
]
}
}
}
}
}
这个查询现在只会匹配具有单个标签 comedy 的文档,而不是任意一个包含 comedy 的文档。
参考:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_finding_multiple_exact_values.html