我已将以下自定义分析器添加到弹性搜索索引中。
{
"index" : {
"analysis" : {
"char_filter" : {
"acc_mapping" : {
"type" : "mapping",
"mappings" : ["/=>"]
}
},
"analyzer" : {
"accno_char_filter" : {
"tokenizer" : "standard",
"char_filter" : ["acc_mapping"]
}
}
}
}
}
基本上我们有很多数据源和遗留数据,帐号可能会有所不同。当前(和大多数数据)格式与acc / vb123 / 123一致,这导致了问题,因为它被标记为acc,vb123和123.我有一个hack解决方案(在我的java应用程序中),其中if只有帐户号码在“硬编码”上搜索完全匹配搜索,即acc / vb123 / 123变为\“acc / vb123 / 123 \”。这不是我自豪的事情,但它在大多数情况下都能胜任(人们往往会搜索帐号或文字,所以我的黑客还没有变得太明显......)我不是弹性搜索方面的专家但我间歇性地试图找到适当的解决方案。
上面的映射将结果从数千减少到数百,但我预计在大多数情况下会减少到1。在调查似乎正在发生的事情是搜索acc / vb123 / 123不再以这种格式获取其他帐户(例如以acc开头或以123结尾)但是它仍然在接收其他fomats with - in so在acc / vb123 / 123上搜索的示例也将返回oldref-123。
使用邮递员我的原始测试搜索是
{
"query" : {
"filtered" : {
"query" : {
"query_string" : {
"query" : "acc/vb123/123",
"fields" : [ "customer.accno" ],
"analyzer": "accno_char_filter"
}
}
}
}
}
用于构建索引的映射文件包含
"accno": {
"type": "string",
"analyzer": "accno_char_filter",
"store": true
},
我认为这意味着就索引和搜索而言,存储和搜索的字段将是1块文本“accvb123123”,因此不会被标记化或分析成任何子组件。
我似乎错了,因为它正在拿起一个 - 就像我解释的oldref-123那样。我猜这可能与使用“tokenizer”:“标准”有关,但我想知道是否有人能解释为什么在我开始撕开它之前会发生这种情况(或者添加一个[“ - =>”]映射到看看这有助于不破坏任何东西!)
提前致谢。
编辑:
实际应用程序为用户提供一个文本输入框,并使用该内容搜索3个字段。一个字段是帐号,1个字段是名称,一个字段是描述。描述可以是一段很长的非常模糊的文字。它可以包含相关帐户的帐号(尽管通常不包含)。通常,搜索完全(或接近)开箱即用。唯一的问题是,设计方式有人可能会在文本框中输入一个帐号,希望看到帐号编号字段的完全匹配(如果是,则可以在描述字段中查看)或者他们可能输入一些通用文本“信用问题Northampton”,他们希望看到信用和问题的结果和Northampton。问题在于,如果他们输入一个帐号,它的设计方式就会得到数千个结果,开箱即用设置为曾经标记过帐号搜索说acc / ab12 / 123搜索acc,ab12和123。我一直在慢慢地逐渐寻找一种方法来阻止acc / ab12 / 123在3个字段中的任何一个中被标记化,这样就可以搜索acc / ab12 / 123并且只获得1个结果(帐号= acc / ab12) / 123)不停止正确搜索文本的可能性。
这是我随着时间的推移逐渐开展的工作,因为有很多解决办法(甚至无视我已经实施的黑客攻击) - 用户可以在搜索文本周围加上引号并搜索[“acc / ab12 / 123“]甚至转到”选项“并选择仅搜索帐号字段。此外,最相关的匹配首先出现,因此数千个结果不会使应用程序无法使用。从开发/支持的角度来看,这是一个非问题(!),但是当他们在使用默认搜索选项搜索帐号时看到数千个结果时,业务会感到不安,并且我想更好地学习弹性搜索定制,所以我逐渐试图根据他们的要求定制它。