PUT test_phrase
{
"mappings" : {
"_doc" : {
"properties" : {
"body" : {
"type" : "text",
"analyzer" : "ik_max_word",
"search_analyzer" : "ik_smart"
}
}
}
}
}
PUT test_phrase/_doc/1
{
"body":"南京市長"
}
GET test_phrase/_search
{
"query": {
"match_phrase": {
"body": "南京市長"
}
}
}
GET test_phrase/_search
{
"query": {
"match_phrase": {
"body": "南京"
}
}
}
複製代碼
# GET test_phrase/_analyze
# {
# "text": ["南京市長"],
# "analyzer": "ik_max_word"
# }
{
"tokens" : [
{
"token" : "南京",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "南京市",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "市長",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
}
]
}
# GET test_phrase/_analyze
# {
# "text": ["南京市長"],
# "analyzer": "ik_smart"
# }
{
"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
}
]
}
複製代碼
org.elasticsearch.index.query.MatchPhraseQueryBuilder#doToQuery
收到查詢請求,轉爲 matchQuery 的 phrase 查詢org.elasticsearch.index.search.MatchQuery#parse
解析請求並轉爲 lucene 請求org.elasticsearch.index.search.MatchQuery#getAnalyzer
肯定分詞器,若是查詢沒指定 analyzer 的話,那麼 phrase 就用 searchQuoteAnalyzer,若是沒有 searchQuoteAnalyzer 則用 searchAnalyzer
org.apache.lucene.util.QueryBuilder#createFieldQuery
進行分詞並判斷有無 graph 和同義詞,若是沒有就用簡單的 phrase 查詢
org.apache.lucene.util.QueryBuilder#analyzePhrase
構建真實查詢,肯定每一個詞的 postion
org.apache.lucene.search.PhraseWeight#getPhraseMatcher
召回倒排鏈,而後判斷 slop,若是爲0,則轉爲ExactPhraseMatcher
org.apache.lucene.search.ExactPhraseMatcher#nextMatch
比較 position 是否相等
search_quote_analyzer
參數,search_quote_analyzer 官方文檔ik_max_word
模式下有三種切分方式,就分別標記 position,而不是原來的混標,這樣就能夠保證 smart 也是 max 的一個子集目前混標方案:html
南京 | 南京市 | 市長 | 長江 | 長江大橋 | 大橋 | 維修 |
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 |
獨立標註方案:apache
南京 | 南京市 | 市長 | 長江 | 長江大橋 | 大橋 | 維修 |
---|---|---|---|---|---|---|
0 | - | 1 | 2 | - | 3 | 4 |
0 | - | 1 | - | 2 | - | 3 |
- | 0 | - | 1 | - | 2 | 3 |
- | 0 | - | - | 1 | - | 2 |
_analyzer
結果能夠看到除了 position
,咱們還有 start_offset
和 end_offset
, 而這兩個比 position 更加準確。所以能夠考慮使用 offset 的diff 一致性來判別。