1. query_string針對索引不存在字段的處理邏輯變化:
如下DLS:語義為查詢此字段(索引内不存在)不包含柔的文檔。
{
"size": 1,
"track_total_hits": true,
"_source": "text_content",
"profile": "true",
"query": {
"query_string": {
"analyzer": "ik_max_word",
"query": """(NOT("柔"))""",
"fields": [
"text_title"
]
}
}
}
- 因為此字段不存在,是以去除NOT改為此字段包含柔的文檔傳回結果為0,這裡不存在歧義,6.7/7.10版本es傳回結果一緻。profile API驗證均如下:
"type" : "MatchNoDocsQuery",
"description" : """MatchNoDocsQuery("empty BooleanQuery")""",
-
添加NOT後,因為字段不存在,查詢不存在字段不包含柔的文檔是傳回0?還是了解為對不帶NOT的語句取非,傳回全部?這裡6和7版本表現不同:
6.7.0版本:
與不帶NOT的結果一緻傳回0條文檔,且profile顯示文法也一緻
7.10.2版本:
做了改變,傳回全部文檔,profile顯示文法添加了一個
如下圖所示。含義大概是NOT語義為不帶NOT取非,不帶NOT傳回0條則NOT應該傳回全部?MatchAllDocsQuery(*:*)
2. minimum_should_match歧義
minimum_should_match
正常了解應該應用于 bool 查詢的 should 子句上,來控制最小比對 should 子句的數量。
預設值(翻譯自官網): 如果 bool 查詢包含至少一個 should 子句,且無 must 和 fliter 子句,則為1;否則為0。
再說上段中7.10版本查詢不存在字段的NOT語句傳回為全部文檔,預設
minimum_should_match
為0,我們把他改成1:
{
"size": 1,
"track_total_hits": true,
"_source": "text_content",
"profile": "true",
"query": {
"query_string": {
"analyzer": "ik_max_word",
"query": """(NOT("柔"))""",
"fields": [
"text_title"
],
"minimum_should_match": "1"
}
}
}
傳回結果為0條,而不是之前的全部文檔。profile分析如下:
奇怪的事情發生了,存在MatchAllDocsQuery子句至少滿足1子句理論上應該還是傳回全部文檔,但是卻傳回了0條?
3. 繼續分析minimum_should_match
需要針對正常的 DSL bool 查詢和 query_string 的NOT AND OR
等bool查詢分别分析minimum_should_match的作用和差異(7.10 版本&針對存在的字段查詢)。
3.1. AND
query_string:
"query": """(("柔")AND("脊"))"""
dsl bool:
"query": {
"bool": {
"must": [
{
"match": {
"text_content": "柔"
}
},
{
"match": {
"text_content": "脊"
}
}
]
}
}
經profile分析兩個語句語一緻為
+text_content:柔 +text_content:脊
,傳回文檔數量也一緻。由
minimum_should_match
特性可知現在它的值為0,修改為1後:dsl bool 和 query_string 文法解析變為
(+text_content:柔 +text_content:脊)~1
且傳回資料條數變為0。
3.2. NOT
query_string:
"query": """(NOT("柔"))"""
dsl bool:
"query": {
"bool": {
"must_not": [
{
"match": {
"text_content": "柔"
}
}
]
}
}
經profile分析兩個語句語一緻如下圖,傳回文檔數量也一緻。
由
minimum_should_match
特性可知現在它的值為0,修改為1後:
dsl bool語義和傳回結果沒有發生變化;
query_string傳回結果為0,且語義變為下圖:
在這裡 query_string 和 dsl bool 的語義産生差異。
3.3 OR
query_string:
"query": """(("柔")OR("脊"))"""
dsl bool:
"query": {
"bool": {
"should": [
{
"match": {
"text_content": "柔"
}
},
{
"match": {
"text_content": "脊"
}
}
]
}
}
由
minimum_should_match
特性可知現在它的值應該為1,經測試:
當它的值設定為0時:語義為
text_content:柔 text_content:脊
;
當它的值設定為1時:語義為
(text_content:柔 text_content:脊)~1
;
且不設定它的值時為0語義,即預設值為0。query_string 和 dsl bool 在此場景下語義和傳回結果一緻。包括設定為2時,語義轉變為
(text_content:柔 text_content:脊)~2
等同于must語義。
**綜上:**在
AND
和
NOT
的情境下
minimum_should_match
均出現異常,隻有在
should
下表現正常。
//TODO
AND OR NOT 組合使用以及minimum_should_match異常原因分析…