1、terms 相當于sql中的in,多值搜索
GET /forum/article/_search
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"tag_cnt": 1
}
},
{
"terms": {
"tag": ["java",”c++”]
}
}
]
}
}
}
}
}
2、搜索瀏覽量在30~60之間的帖子
GET /forum/article/_search
{
"query": {
"constant_score": {
"filter": {
"range": {
"view_cnt": {
"gt": 30,
"lt": 60
}
}
}
}
}
}
gte lte包含
3、搜索標題中包含java或elasticsearch的
GET /forum/article/_search
{
"query": {
"match": {
"title": "java elasticsearch"
}
}
}
如果想同時滿足,可以加operator
GET /forum/article/_search
{
"query": {
"match": {
"title": {
"query": "java elasticsearch",
"operator": "and"
}
}
}
}
在es內部,會轉換成下面的去執行
{
"bool": {
"must": [
{ "term": { "title": "java" }},
{ "term": { "title": "elasticsearch" }}
]
}
}
使用minimum_should_match,必須至少匹配其中的多少個關鍵字,才能作為結果返回,可以用數字也可以使用百分比
GET /forum/article/_search
{
"query": {
"match": {
"title": {
"query": "java elasticsearch hadoop spark,",
"minimum_should_match": “75”%
}
}
}
}
也可以使用下面的should寫法,當然,上面的語法,在es內部都會處理成下面的去查詢
GET /forum/article/_search
{
"query": {
"bool": {
"should": [
{"match": {
"title": "java"
}},
{"match": {
"title": "elasticsearch"
}},
{
"match": {
"title": "hadoop"
}
},
{
"match": {
"title": "spark"
}
}
],
"minimum_should_match":3
}
}
}
4、boost的搜索條件權重控制
指定查詢的內容中,什么排在最前面,默認是一樣的,數值是你所查詢中的條件個數+1,這樣才會最優在前
GET /forum/article/_search
{
"query": {
"bool": {
"should": [
{"match": {
"title": {
"query":"java"
}
}},
{"match": {
"title": {"query":"elasticsearch"}
}},
{
"match": {
"title": {"query":"hadoop"}
}
},
{
"match": {
"title":{"query":"spark",
"boost":5}
}
}
]
}
}
}
5、多shard場景下relevance score不準確問題大揭秘
如果你的一個index有多個shard的話,可能搜索結果會不準確
解決:
(1)生產環境下,數據量大,盡可能實現均勻分配
(2)測試環境下,將索引的primary shard設置為1個,number_of_shards=1
(3)測試環境下,搜索附帶search_type=dfs_query_then_fetch參數,會將local IDF取出來計算從新計算,但是生產環境下,不推薦這個參數,因為性能很差。
GET /forum/article/_search?search_type=dfs_query_then_fetch
6、dis_max實現best fields策略進行多字段搜索
(1)****搜索title或content中包含java或solution的帖子
GET /forum/article/_search
{
"query": {
"bool": {
"should": [
{"match": { "title": "java solution"}},
{"match": {
"content": "java solution"
}}
]
}
}
}
{
"_index": "forum",
"_type": "article",
"_id": "4",
"_score": 0.7120095,
"_source": {
"articleID": "QQPX-R-3956-#aD8",
"userID": 2,
"hidden": true,
"postDate": "2017-01-02",
"tag": [
"java",
"elasticsearch"
],
"tag_cnt": 2,
"view_cnt": 80,
"title": "this is java, elasticsearch, hadoop blog",
"content": "elasticsearch and hadoop are all very good solution, i am a beginner"
}
},
{
"_index": "forum",
"_type": "article",
"_id": "5",
"_score": 0.56008905,
"_source": {
"articleID": "DHJK-B-1395-#Ky5",
"userID": 3,
"hidden": false,
"postDate": "2017-03-01",
"tag": [
"elasticsearch"
],
"tag_cnt": 1,
"view_cnt": 10,
"title": "this is spark blog",
"content": "spark is best big data solution based on scala ,an programming language similar to java"
}
},
(2)結果分析
期望的是doc5,結果是doc2,doc4排在了前面
計算每個document的relevance score:每個query的總分數,乘以matched query數量,除以總query數量
算一下doc4的分數
{ "match": { "title": "java solution" }},針對doc4,是有一個分數的
{ "match": { "content": "java solution" }},針對doc4,也是有一個分數的
所以是兩個分數加起來,比如說,1.1 + 1.2 = 2.3
matched query數量 = 2
總query數量 = 2
2.3 * 2 / 2 = 2.3
算一下doc5的分數
{ "match": { "title": "java solution" }},針對doc5,是沒有分數的
{ "match": { "content": "java solution" }},針對doc5,是有一個分數的
所以說,只有一個query是有分數的,比如2.3
matched query數量 = 1
總query數量 = 2
2.3 * 1 / 2 = 1.15
doc5的分數 = 1.15 < doc4的分數 = 2.3
(3)best fields策略,dis_max
best fields策略,就是說,搜索到的結果,應該是某一個field中匹配到了盡可能多的關鍵詞,被排在前面;而不是盡可能多的field匹配到了少數的關鍵詞,排在了前面
dis_max語法,直接取多個query中,分數最高的那一個query的分數即可
{ "match": { "title": "java solution" }},針對doc4,是有一個分數的,1.1
{ "match": { "content": "java solution" }},針對doc4,也是有一個分數的,1.2
取最大分數,1.2
{ "match": { "title": "java solution" }},針對doc5,是沒有分數的
{ "match": { "content": "java solution" }},針對doc5,是有一個分數的,2.3
取最大分數,2.3
然后doc4的分數 = 1.2 < doc5的分數 = 2.3,所以doc5就可以排在更前面的地方,符合我們的需要
GET /forum/article/_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "java solution" }},
{ "match": { "content": "java solution" }}
]
}
}
}
(4)、tie_breaker參數優化dis_max搜索效果
dis_max只取某一個query最大的分數,完全不考慮其他query的分數,可能會導致排序不一對,可以使用tie_breaker將其他query的分數也考慮進去
GET /forum/article/_search
{
"query": {
"dis_max": {
"queries": [{"match": {
"title": "java solution"
}},{"match": {
"content": "java solution"
}}],"tie_breaker": 0.3
}
}
}
7、multi_match語法實現dis_max+tie_breaker
GET /forum/article/_search
{
"query": {
"multi_match": {
"query": "java solution",
"fields": ["title^2","content"],
"type": "best_fields",
"tie_breaker": 0.3,
"minimum_should_match":"70%"
}
}
}