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 一致性来判别。