【发布时间】:2015-08-06 23:47:56
【问题描述】:
我目前在 Symfony2 中使用 FOSElasticaBundle,我很难尝试构建一个匹配最长前缀的搜索。
我知道 Internet 上有 100 个示例使用它来执行类似自动完成的搜索。但是,我的问题有点不同。
在自动完成类型的搜索中,数据库包含最长的字母数字字符串(字符长度),用户只提供最短的部分,假设用户键入“jho”,Elasticsearch 可以轻松提供“Jhon, Jhonny, Jhonas ”。
我的问题是倒退,我想提供最长的字母数字字符串,我希望 Elasticsearch 为我提供数据库中最大的匹配项。
例如:我可以提供“123456789”,我的数据库可以有 [12,123,14,156,16,7,1234,1,67,8,9,123456,0],在这种情况下,最长前缀匹配用户提供的号码的数据库是“123456”。
我刚开始使用 Elasticsearch,所以我真的没有接近工作设置或任何东西。
如果有任何信息不清楚或遗漏,请告诉我,我会提供更多详细信息。
更新 1(使用 Val 的第二次更新)
Settings:
curl -XPUT localhost:9200/tests -d '{
"settings": {
"analysis": {
"analyzer": {
"edge_ngram_analyzer": {
"tokenizer": "edge_ngram_tokenizer",
"filter": [ "lowercase" ]
}
},
"tokenizer": {
"edge_ngram_tokenizer": {
"type": "edgeNGram",
"min_gram": "2",
"max_gram": "25"
}
}
}
},
"mappings": {
"test": {
"properties": {
"my_string": {
"type": "string",
"fields": {
"prefix": {
"type": "string",
"analyzer": "edge_ngram_analyzer"
}
}
}
}
}
}
}'
Query:
curl -XPOST localhost:9200/tests/test/_search?pretty=true -d '{
"size": 1,
"sort": {
"_script": {
"script": "doc.my_string.value.length()",
"type": "number",
"order": "desc"
},
"_score": "desc"
},
"query": {
"filtered": {
"query": {
"match": {
"my_string.prefix": "8092232423"
}
},
"filter": {
"script": {
"script": "doc.my_string.value.length() <= maxlength",
"params": {
"maxlength": 10
}
}
}
}
}
}'
With this configuration the query returns the following results:
{
"took" : 61,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1754,
"max_score" : null,
"hits" : [ {
"_index" : "tests",
"_type" : "test",
"_id" : "AU8LqQo4FbTZPxBtq3-Q",
"_score" : 0.13441172,
"_source":{"my_string":"80928870"},
"sort" : [ 8.0, 0.13441172 ]
} ]
}
}
额外问题
我想为该搜索提供一个数字数组,并以一种有效的方式为每个数字获取匹配的前缀,而不必每次都执行查询
【问题讨论】:
-
我们在 MySQL 中进行了类似的搜索,我们使用的技术是查询所有匹配项,然后在 php.ini 中计算最大的匹配项。所以搜索所有匹配[1,12,123,1234,12345,123456,1234567,12345678,123456789]的项目。然后对于每个结果检查它是否是最长的字符串。我也对更好的解决方案感兴趣。您的 elasticsearch 数据是来自 KeyValue 还是 Object DB?
-
我目前正在这样做,我搜索所有结果并准备一棵二叉树,然后搜索最长的前缀 bht 我担心内存管理和那些东西......目前有该列表中有 300,000 个条目。另外,您如何仅查询匹配结果?至于你的问题,可以是任何一种方式
-
快速问题:您是否希望响应仅包含比输入字符串短 的匹配项或更长的匹配项也可以?即,如果我输入“123456789”并且数据库包含“123456789abcd”,这是否也符合匹配条件?
-
是的,这符合匹配条件,任何以该前缀(最长前缀)开头的都是有效匹配
标签: symfony elasticsearch elastica foselasticabundle longest-prefix