关键词搜索工具好站网,南昌做网站优化的公司,机械生产erp软件,物流网络规划文章目录 前言一、多条件查询#xff1a;bool query二、更加精准查询#xff1a;dis_max query总结 前言
这里再接着上一篇文章继续记录。非常感谢江南一点雨松哥的文章。 欢迎大家去查看#xff0c;地址#xff1a;http://www.javaboy.org 一、多条件查询#xff1a;boo… 文章目录 前言一、多条件查询bool query二、更加精准查询dis_max query总结 前言
这里再接着上一篇文章继续记录。非常感谢江南一点雨松哥的文章。 欢迎大家去查看地址http://www.javaboy.org 一、多条件查询bool query
bool query 可以将任意多个简单查询组装在一起有四个关键字可供选择四个关键字所描述的条件可以有一个或者多个。
1、must文档必须匹配 must 选项下的查询条件。2、should文档可以匹配 should 下的查询条件也可以不匹配。3、must_not文档必须不满足 must_not 选项下的查询条件。4、filter类似于 must但是 filter 不评分只是过滤数据。
例如查询楼层大于20层小于25且为城市住宅地址为草堂街道或者不是光华街道的数据
GET /building_info/_search
{query: {bool: {must: [{range: {floor: {gte: 20,lte: 25}}},{term: {type: {value: 城市住宅}}}],should: [{match: {address: 草堂街道}}],must_not: [{match: {address: 光华街道}}]}}
}这里还涉及到一个关键字minmum_should_match 参数。
minmum_should_match 参数在 es 官网上称作最小匹配度。在之前学习的 multi_match 或者这里的 should 查询中都可以设置 minmum_should_match 参数。
假设我们要做一次查询查询 address 中包含 杜甫草堂街道 关键字的文档
GET /building_info/_search
{query: {match: {address: {query: 杜甫草堂街道}}}
}分词如下
{tokens : [{token : 杜甫,start_offset : 0,end_offset : 2,type : CN_WORD,position : 0},{token : 草堂,start_offset : 2,end_offset : 4,type : CN_WORD,position : 1},{token : 街道,start_offset : 4,end_offset : 6,type : CN_WORD,position : 2}]
}分词后的 term 会构造成一个 should 的 bool query每一个 term 都会变成一个 term query 的子句。换句话说上面的查询和下面的查询等价
GET /building_info/_search
{query: {bool: {should: [{term: {address: {value: 杜甫}}},{term: {address: {value: 草堂}}},{term: {address: {value: 街道}}}]}}
}在这两个查询语句中都是文档只需要包含词项中的任意一项即可文档就回被返回在 match 查询中可以通过 operator 参数设置文档必须匹配所有词项。 如果想匹配一部分词项就涉及到一个参数就是 minmum_should_match即最小匹配度。即至少匹配多少个词。
GET building_info/_search
{query: {match: {address: {query: 杜甫草堂北路,operator: and}}}
}GET building_info/_search
{query: {bool: {should: [{term: {address: {value: 杜甫}}},{term: {address: {value: 草堂}}},{term: {address: {value: 街道}}}],minimum_should_match: 50%}},from: 0,size: 5
}50% 表示词项个数的 50%。
如下两个查询等价参数 3 是因为查询关键字分词后有 3项
GET building_info/_search
{query: {match: {address: {query: 杜甫草堂街道,minimum_should_match: 3}}}
}
# 关键字分词后有3个词
GET building_info/_search
{query: {match: {name: {query: 杜甫草堂街道,operator: and}}}
}二、更加精准查询dis_max query
假设现在有两本书
PUT blog
{mappings: {properties: {title:{type: text,analyzer: ik_max_word},content:{type: text,analyzer: ik_max_word}}}
}POST blog/_doc
{title:如何通过Java代码调用ElasticSearch,content:松哥力荐这是一篇很好的解决方案
}POST blog/_doc
{title:初识 MongoDB,content:简单介绍一下 MongoDB以及如何通过 Java 调用 MongoDBMongoDB 是一个不错 NoSQL 解决方案
}现在假设搜索 Java解决方案 关键字但是不确定关键字是在title还是在 content所以两者都搜索
GET blog/_search
{query: {bool: {should: [{match: {title: java解决方案}},{match: {content: java解决方案}}]}}
}搜索结果如下 肉眼观察感觉第二个和查询关键字相似度更高但是实际查询结果并非这样。
要理解这个原因我们需要来看下 should query 中的评分策略 1、首先会执行 should 中的两个查询 2、对两个查询结果的评分求和 3、对求和结果乘以匹配语句总数 4、在对第三步的结果除以所有语句总数 反映到具体的查询中
前者 1、title 中 包含 java假设评分是 1.1 2、content 中包含解决方案假设评分是 1.2 3、有得分的 query 数量这里是 2 4、总的 query 数量也是 2 最终结果1.11.2*2/22.3 后者 1、title 中 不包含查询关键字没有得分 2、content 中包含解决方案和 java假设评分是 2 3、有得分的 query 数量这里是 1 4、总的 query 数量也是 2 最终结果2*1/21 在这种查询中title 和 content 相当于是相互竞争的关系所以我们需要找到一个最佳匹配字段。
为了解决这一问题就需要用到 dis_max querydisjunction max query分离最大化查询匹配的文档依然返回但是只将最佳匹配的评分作为查询的评分。
GET blog/_search
{query: {dis_max: {queries: [{match: {title: java解决方案}},{match: {content: java解决方案}}]}}
}结果如下 在 dis_max query 中还有一个参数 tie_breaker取值在01在 dis_max query 中是完全不考虑其他 query 的分数只是将最佳匹配的字段的评分返回。但是有的时候我们又不得不考虑一下其他 query 的分数此时可以通过 tie_breaker 来优化 dis_max query。tie_breaker 会将其他 query 的分数乘以 tie_breaker然后和分数最高的 query 进行一个综合计算。 总结
这篇文章记录还算是比较有用的东西。