给定来自用户的自由格式查询,我试图确定它是否包含位置短语。
示例:给定自由格式的查询"san francisco ca中的纽约风格比萨饼“,并给出包含”丹佛公司“、”迈阿密fl“、”纽约纽约“、”旧金山ca“、”巴黎法国“等位置短语的文档索引,则匹配的文档将包含位置短语"san francisco ca”。
包含位置短语的索引还包含允许的排列,在单独的文档中。在上面的例子中,我可能有"san francisco ca“、"san francisco california",还有可能还有"sf”、"bay area ca“等其他文件,这些文档都是索引中的单独文档。大写和标点符号将被预先丢弃,所以查询“纽约风格的披萨,在旧金山,在加州”将变成“纽约风格的披萨在旧金山,在加州”。
我还应该提到,如果有一种更好或需要的方法来为特定类型的查询索引位置,例如在不同的领域中有"city“和"state”和"country“,我也可以这样做,而且我非常愿意听取建议。
到目前为止我尝试过的是:
我没试过的原因是:
我花了3-4天来解决这个问题,希望能得到一些温和的指导。示例查询/索引/映射将是很棒的,但是即使让我知道我应该使用的查询类型(以及索引和映射),也会非常有用,所以我至少可以“把正确的树树皮化”!
我愿意将其他工具与ES结合使用,只要它们是开源的、可免费获得的、支持和使用得相当好的。位置数据库包含~1M记录。
奖励:我假设位置短语(如果有的话)将接近查询的末尾。以某种方式感觉到这一点或相应地促进结果将是很好的。注意,我不想将此作为绝对要求;如果用户提交查询“我希望旧金山ca比萨饼场所拥有纽约风格的比萨饼”,给定前面描述的索引的唯一有效位置短语是"san francisco ca“,这应该是匹配的。
奖金2X:我有每个地点的人口信息。为更高的人口稍微提高结果的一些方法也是很棒的(我已经尝试了function_score与field_value_factor函数和ln1p修饰符,它看起来很好,但不确定如果我最终使用percolator,它将如何工作)。
奖励3X!:容纳轻微的排字,例如“旧金山”将是很好的。
我使用的是ElasticSearch 1.3.2。
谢谢!!
编辑:为了清楚起见,我正在寻找短语搜索,当索引短语比查询短时,正如这里很好地描述的,但不幸的是没有完全解决:
发布于 2014-11-07 10:03:38
这里有一些建议,即使我有一些怀疑,我理解你的要求是正确的。
基本思想是操作您在索引(位置)中放置的内容,因为您希望匹配比实际存储在文档中的内容更大的内容。此外,我想强调的是,我不认为这将是一个黑白的情况下,你要么得到一个(正确的)答案或根本没有答案。比赛总会有“分数”。
另一点是,您需要知道如何操作您的位置,这样,考虑到您预测的用户将使用什么查询,这些操作将帮助您处理大多数案例(而不是all cases)。更好地说,索引位置和您对它们执行的操作的组合将给您更高的匹配大多数查询的机会。
以下是一些具体的想法:
"settings": {
"analysis": {
"filter": {
"my_shingle_filter": {
"type": "shingle",
"min_shingle_size": 2,
"max_shingle_size": 2,
"output_unigrams": true // this is true for situations where you have "paris france" in locations but user searches for "paris"
}
},
"analyzer": {
"my_shingle_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"my_shingle_filter"
]
}
}
}
},
"mappings": {
"locations": {
"properties": {
"name": {
"type": "string",
"analyzer": "my_shingle_analyzer",
"fields": {
"full": {
"type": "string",
"analyzer": "keyword"
}
}}}}}name.full )。
第一个示例来自您的一个查询示例:“位于旧金山的纽约风格比萨饼”。对于索引中的每个位置,添加另一个应该具有in前缀的字段:in san francisco、in new york等。"transform": [
{
"script": "full_plus_in = 'in ' + ctx._source['name']; ctx._source['name.full_plus_in'] = full_plus_in",
"lang": "groovy"
}
...第二个例子是将places后缀添加到映射中的一个新字段。假设在您的预测中,像“旧金山新风格比萨饼的位置”这样的查询可以被认为是频繁的:
{"script": "full_plus_places = ctx._source['name'] + ' places'; ctx._source['name.full_plus_places'] = full_plus_places",
"lang": "groovy"}把所有这些放在一起是一个初步的映射:
{
"settings": {
"analysis": {
"filter": {
"my_shingle_filter": {
"type": "shingle",
"min_shingle_size": 2,
"max_shingle_size": 2,
"output_unigrams": true
}
},
"analyzer": {
"my_shingle_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"my_shingle_filter"
]
}
}
}
},
"mappings": {
"locations": {
"transform": [
{
"script": "full_plus_in = 'in ' + ctx._source['name']; ctx._source['name.full_plus_in'] = full_plus_in",
"lang": "groovy"
},
{"script": "full_plus_places = ctx._source['name'] + ' places'; ctx._source['name.full_plus_places'] = full_plus_places",
"lang": "groovy"}
],
"properties": {
"name": {
"type": "string",
"analyzer": "my_shingle_analyzer",
"fields": {
"full": {
"type": "string",
"analyzer": "keyword"
},
"full_plus_in": {
"type": "string",
"analyzer": "keyword"
},
"full_plus_places": {
"type": "string",
"analyzer": "keyword"
}
}
}
}
}
}
}测试数据:
{"index":{}}
{"name":"denver co"}
{"index":{}}
{"name":"miami fl"}
{"index":{}}
{"name":"new york city ny"}
{"index":{}}
{"name":"san francisco ca"}
{"index":{}}
{"name":"paris france"}
{"index":{}}
{"name":"bay area ca"}
{"index":{}}
{"name":"dallas texas"}
{"index":{}}
{"name":"san francisco california"}
{"index":{}}
{"name":"new york city new york"}示例查询:
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "i want san francisco ca places having new york style pizza"
}
}
],
"should": [
{"match": {
"name.full": "i want san francisco ca places having new york style pizza"
}},
{"match": {
"name.full_plus_in": "i want san francisco ca places having new york style pizza"
}},
{"match": {
"name.full_plus_places": "i san francisco ca places having new york style pizza"
}}
]
}
}
}第一个匹配位置应该是最好的(考虑到它得到的分数)。
https://stackoverflow.com/questions/26740620
复制相似问题