使用的版本是6.8,配置有ik中文分詞器,並且已經在字段上設置了屬性爲keyword,但是使用term查詢無法生效。
@Field(type = FieldType.Keyword)
QueryBuilder queryBuilder = QueryBuilders.termQuery("source", "淘寶");
準確來說並不是無法生效,而是沒有查詢出數據。首先說一下對於term查詢的語義:
term query會去倒排索弓|中尋找確切的term,它並不知道分詞器的存在。這種查詢適合keyword、numeric. date.
term表示查詢某個字段裏含有某個關鍵詞的文檔,terms表示查詢某個字段裏合有多個關鍵詞的文檔注意:查詢某個字段裏含有某個關鍵詞的文檔,這句話就說明了直接對字段進行term查詢實際上還是模糊搜索,區別只不過是不會對搜索的輸入字符串進行分詞處理而已。如果想通過term查詢到數據,那麼term查詢的字段在索引庫中就必須有與term查詢條件相同的索引詞,否則就是無法查詢到結果的。
最後發現原因還是在於keyword這個屬性的語義。
keyword屬性,網上很多文章說在字段上設置該屬性表示對於該字段不進行分詞索引,但實際上該字段仍然會被分詞,所以如果分詞之後的索引庫中不包含該字段的完整詞,那麼直接對該字段用上面的term查詢是完全無法查詢的。
可以嘗試將檢索條件”淘寶“改爲”淘“或者”寶“就可以檢索出結果,這說明還是進行了分詞處理。
那設置keyword有什麼用?
實際上,keyword屬性的設置是添加了一個額外字段,這個字段就是source.keyword,也就是es在source字段之下額外生成添加了一個屬性字段是keyword,這個keyword纔是真正的不分詞的索引字段,source.keyword字段纔是真正意義上的不分詞處理字段。而索引也是索引該字段纔是真正的精確匹配。大概類似於下面的maping
"mapping": {
"properties": {
"id": {
"type": "long"
},
"searchField": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
所以,在對keyword屬性字段進行精確查詢時,應該改爲如下代碼
QueryBuilder queryBuilder = QueryBuilders.termQuery("source.keyword", "淘寶");