我正在使用Elasticsearch(v 1.7.3,带有Java传输客户端)来搜索人名数据库 . 我正在利用一堆可用的语音算法(DoubleMetaphone,RefinedSoundex等)来索引我的名字字段并存储它们 . 但是,我需要的评分算法是计算输入令牌与索引中的一个接近度的百分比 .
例如:
以下文档,使用语音算法进行索引时:
{
"FullName": "Christopher Cruickshank"
}
扩展为(使用analyze api获取的输出):
{
"tokens": [
{
"token": "C3090360109",
"start_offset": 0,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "christopher",
"start_offset": 0,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "K3936",
"start_offset": 0,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "KRST",
"start_offset": 0,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "C3903083",
"start_offset": 12,
"end_offset": 23,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "cruickshank",
"start_offset": 12,
"end_offset": 23,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "K3935",
"start_offset": 12,
"end_offset": 23,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "KRKX",
"start_offset": 12,
"end_offset": 23,
"type": "<ALPHANUM>",
"position": 2
}
]
}
现在在搜索时间内,当我查询:
{
"match": {
"FullName": {
"query": "Cristopher Krukshank",
"boost": 10.0
}
}
}
我想要做的是根据索引中匹配的令牌数量对结果进行评分 .
即:
(Number of matched tokens per term / Total number of expanded tokens per term) * Boost
虽然这可能在概念上有效,但我想知道是否有更好的方法来实现同样的目标 .
此外,我倾向于在索引时间内(通过在一个字段中存储总标记的数量)推动复杂性和逻辑的大部分,因此我的搜索逻辑将更简单 . 如果这是一种合理的方法,那么我想知道在索引过程中使用analyze api是否存在任何技术含义,特别是当批量索引用于数百万个名称时 . 我猜测将为每个原始令牌调用Analyze API,并且每个令牌都是扩展的令牌(这可能是巨大的!) .
如果这根本不是一个合理的方法,那么请有人指点或分享一些经验吗?
我还想到的另一个选择是在查询时调用analyze api并使用“explain”选项将查询发送到elasticsearch,然后在explain部分中进行字符串匹配以计算出匹配的令牌数 .