文章目录
4.24 基于词项和基于全文的搜索
基于term的查询
- Term的重要性
- Term是表达语意的最小单位。搜索和利用统计语言模型进行自然语言处理都需要处理Term
- 特点
- Term Level Query: Term Query / Range Query / Exists Query / Prefix Query / Wildcard Query
- 在ES中,Term查询,对输入不做分词。会将输入做为一个整体,在倒排索引中查找准确的词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分 - 例如“Apple Store”
- 可以通过Constant Score将查询转换成一个Filtering,避免算分,并利用缓存,提高性能。
POST /products/_search
{
"explain":true
"query":{
"constant_score":{
"filter":{
"term":{
"productID.keyword":"1111-2222-3333-4444"
}
}
}
}
}
示例
基于全文本的查询
- 基于全文本的查询
- Match Query / Match Phrase Query / Query String Query
- 特点
- 索引和搜索时都会进行分词,查询字符串先传递到一个合适的分词器,然后生成一个供查询的词项列表
- 查询时候,先会对输入的查询进行分词,然后每个词项逐个进行底层的查询,最终将结果进行合并。并为每个文档生成一个算分。-例如查“Matrix reloaded”,会查到包括Matrix 或者 reload的所有结果。
POST movies/_search
{
"query":{
"match":{
"title":{
"query":"Matrix reloaded"
}
}
}
}
POST movies/_search
{
"query":{
"match":{
"title":{
"query":"Matrix reloaded"
"operator":"AND"
}
}
}
}
POST movies/_search
{
"query":{
"match":{
"title":{
"query":"Matrix reloaded"
"minimum_should_match":2
}
}
}
}
POST movies/_search
{
"query":{
"match_phrase":{
"title":{
"query":"Matrix reloaded"
"slop":1
}
}
}
}
所以term查询与全文本查询最根本的区别在于是否进行分词处理后再进行查询。
4.25节-结构化搜索
- 结构化搜索(Structured search)是指对结构化数据的搜索
- 日期,布尔型和数字都是结构化的
- 文本也是可以结构化的
- 如彩色笔可以有离散的颜色集合:红,绿,蓝
- 一个博客可能被标记了标签,例如,分布式,和搜索。
- 网站上的商品都有UPCs,或者其它的唯一的标识,它们都需要遵从严格规定的,结构化的格式。
GET products/_search
{
"query":{
"constant_score":{
"filter":{
"range":{
"price":{
"gte":20,
"lte":30
}
}
}
}
}
}
GET products/_search
{
"query":{
"constant_score":{
"filter":{
"range":{
"date":{
"gte":now-1y
//就是查1年以前的
}
}
}
}
}
}
GET products/_search
{
"query":{
"constant_score":{
"filter":{
"exists":{
"field":"date"
//就是查有date的,排除非空的值。
}
}
}
}
}
4.26节-搜索的相关性算分
4.27节-Query&Filtering与多字符串多字段查询
bool 查询
- 一个bool查询,是一个或者多个查询子句的组合
- 总共包括4种句子。基中2种会影响算分,2种不影响算分
- 相关性并不只是全文本检索的专利。也适用于yes|no 的子句,匹配的子句越多,相关性评分越高。如果多条查询子句被合并为一条复合查询语句,比如bool查询,则每个查询子句计算得出的评分会被合并到总的相关性评分中:
关键词 | 作用 |
---|---|
must | 必需匹配,贡献算分 |
should | 选择性匹配,贡献算分 |
must_not | Filter Context,查询语句,必需不能匹配 |
filter | Filter Context 必需匹配,但是不贡献算分 |
POST /products/_search
{
"query":{
"bool":{
"must":{
"term":{"price":"30"}
},
"filter":{
"term":{"available":"true"}
},
"must_not":{
"range":{
"price":{"lte":10}
}
},
"should":[
{"term":{"productID.keyword":"1111-2222-3333"}},
{"term":{"productID.keyword":"4444-5555-6666"}}
]
"minimum_should_match":1
}
}
}
bool查询中:
- 子查询可以任意顺序出现
- 可以嵌套多个查询
- 如果你的bool查询中,没有must条件,should中必需至少满足一条查询。
bool 嵌套查询:
POST /products/_search
{
"query":{
"bool":{
"must":{
"term":{"price":"30"}
},
"should":[
"bool":{
"must_not":{
"term":{
"available":"false"
}
}
}
],
"minimum_should_match":1
}
}
}
这个实现了should_not的逻辑查询。
控制字段的Boosting
POST blogs/_search
{
"query":{
"bool":{
"should":[
{
"match":{
"title":{
"query":"apple,ipad",
"boost":4
}
}
},
{
"match":{
"content":{
"query":"apple,ipad",
"boost":1
}
}
}
]
}
}
}
- Boosting是控制相关度的一种手段
- 索引,字段,或查询子条件
- 参数boost的含义
- 当boost>1时,打分的相关度相对性提升
- 当0<boost<1时,打分的权重相对性降低
- 当boost<0时,贡献负分。
单字符串多字段查询:Dis Max Query
POST blogs/_search
{
"explain": true,
"query":{
"bool":{
"should":[
{"match":{"title":"Brown fox"}},
{"match":{"body":"Brown fox"}}
]
}
}
}
这是从两个文档中搜同一个Brown
Disjunction Max Query查询
- 上例中,title和body相互竞争
- 不应该将分数得意叠加,而是应该找到单个最佳匹配的字段的评分
- Disjunction Max Query
- 将任何与任一查询匹配的文档作为结果返回。采用字段上最匹配的评分最终评分返回。
4.29节,单字符串多字段查询:Multi Match
三种场景
- 最佳字段(Best Fields)
- 当字段之间相互竞争,又相互关联。例如title和body这样的字段。评分来自最匹配字段。
- 多数字段 (Most Fields)
- 处理英文内容时:一种常见的手段是,在主字段(English Analyzer),抽取词干,加入同义词,以匹配更多的文档。相同的文本,加入子字段(Standard Analyzer),以提供理加精确的匹配。其它字段作为匹配文档提高相关度的信号。匹配字段越多则越好。
- 混合字段 (Cross Field)
- 对于某些实体,例如人名,地址,图书信息。需要在多个字段中确定信息,单个字段只能作为整体的一部分。希望在任何这些列出的字段中找到尽可能多的词。