- 最近业务需求需要实现搜索的多个词在同段或者同句的功能,索引是按照同段落入到es的,自己实现了分词器来设置同句的position,同段的position在建立索引时设置,下面展示当时遇到的难点.比如搜索词:未就 股权转让 个人所得税, 在未就这个词落入到es会变成两个词项(term)未和就,股权转让和个人所得税有全粒度的分词(即原词在分词中),原先实现是通过match_phrase实现,查询query如下:
must[
{
"match_phrase":{
"content":{
"query":"未 就 股权转让 个人所得税",
"slop":10000 // 这个是段落设置的position
}
}
},
{
"match_phrase":{
"content":{
"query":"未 就",
"slop":0
}
}
},
{
"match_phrase":{
"content":{
"query":"股权转让",
"slop":0
}
}
},
{
"match_phrase":{
"content":{
"query":"个人所得税",
"slop":0
}
}
}
]
上面这个query在实际中会存在两个问题:
- 在实现同段搜索时未 和 就这两个词是分开的,标红也会针对未和就单个词进行标红.
- must的每个条件是作用在全文的,也就是说slop为0的"未就"查询只保证文章中出现了这个词,不保证和股权转让 、个人所得税是在同段的。
解决:
match_phrase底层实现是通过span进行实现的,而span_near支持嵌套查询。
"span_near":{
"clauses":[
{
"span_near":{
"clauses":[
{
"span_term":{"content":"未"}
},
{
"span_term":{"content":"就"}
}
],
"slop":0
}
},
{
"span_term":{"content":"股权转让"}
},
{
"span_term":{"content":"个人所得税"}
}
],
"slop":10000,
"in_order":"false"
}