【发布时间】:2014-07-09 20:05:31
【问题描述】:
是否可以在 ElasticSearch 中结合通配符匹配和 ngram?我已经在使用长度为 3-11 的 ngram。
作为一个非常小的例子,我有记录 C1239123 和 C1230123。用户想要返回这两个。这是他们唯一知道的信息:C123?12
上述情况不适用于我的完整匹配分析器,因为查询最后缺少 3。我的印象是通配符匹配可以开箱即用,但是如果我执行类似于上面的搜索,我会得到乱码。
查询:
.Search<ElasticSearchProject>(a => a
.Size(100)
.Query(q => q
.SimpleQueryString(query => query
.OnFieldsWithBoost(b => b
.Add(f => f.Summary, 2.1)
.Add(f => f.Summary.Suffix("ngram"), 2.0)
.Query(searchQuery))));
分析器:
var projectPartialMatch = new CustomAnalyzer
{
Filter = new List<string> { "lowercase", "asciifolding" },
Tokenizer = "ngramtokenizer"
};
分词器:
.Tokenizers(t=>t
.Add("ngramtokenizer", new NGramTokenizer
{
TokenChars = new[] {"letter","digit","punctuation"},
MaxGram = 11,
MinGram = 3
}))
编辑: 主要目的是让用户准确地告诉搜索引擎未知字符在哪里。这保留了匹配顺序。我不对查询进行语法分析,只对索引字段进行语法分析。
EDIT 2 获得更多测试结果: 我把我之前的例子简化得太多了。乱码是由标点过滤器引起的。有一个适当的例子,没有乱码,但结果不会按相关顺序返回。看到下面,我不确定为什么前 2 个结果完全匹配。 Ngram 不适用于查询。
搜索 c.a123?.7?0 会按以下顺序给出结果:
- C.A1234.560
- C.A1234.800
- C.A1234.700
- C.A1234.950
【问题讨论】:
-
你试过
c123?12*吗?在 ElasticSearch 中结合通配符匹配和 ngram 很好,但您必须了解它是如何工作的。否则会返回意想不到的结果 -
@Duc.Duong 我试过了。它确实返回结果,但它们似乎与查询无关。
-
你能发布匹配的结果吗?我们可以对此进行更多调查
-
@Duc.Duong 我添加了一个新示例。它似乎工作......有点。一个通配符似乎很好。多个通配符效果不佳。一种似乎更有可能的可能性是,由于数据包含用于分隔数字组的小数,因此将标准分析器应用于查询可能会产生干扰。
-
您可以安装
inquisitor插件来查看C.A1234.560、C.A1234.800的实际索引数据,也许我们可以找到一些线索为什么它总是匹配。顺便说一句,如果您可以将创建/索引示例数据/查询的脚本编写到 SH 文件中并将其发布到 GIST,那就太好了,它将帮助我快速运行并检查问题。否则您可以发布发送到 ES 的最终查询吗?您可以在 NEST 的搜索响应中找到它
标签: elasticsearch