看,灰机...

es dsl 多索引多字段地理位置过滤请教

Elasticsearch | 作者 notyy | 发布于2019年10月20日 | 阅读数:2037

我现在使用的es版本是6.8, 有两个索引, 一个是商家, 一个是商品.  这两个索引的文档都有 name 字段, 分别用于存储商家名称和菜品名称; 
商家文档还有一个商家位置的字段 location, 是 geo_point 字段类型, 商品文档上没有 location 字段. 

现在要实现这样一个需求, 要求同时满足以下两个条件
1. 根据 name 字段匹配结果, 比如顾客输入 "火锅" ,  那么商家名称或者商品名称中包含 "火锅" 的内容必须出现
2. 根据顾客的定位, 只匹配顾客 5km 以内的商家


单独实现这两个功能不复杂, 先使用一条语句过滤位置和商家名称,  然后在使用第二个语句查询过滤后的商家下面的商品, 然后在同时把满足条件的商家和商品信息返回.  但是这样的话我需要用2条查询语句才能做到.

请教: 如果想只用一条查询语句, 只通过一次查询就得出结果, 这个 dsl 应该怎么写? 
 
商家文档的 mapping 定义大致如下
{
"shops" : {
"mappings" : {
"_doc" : {
"properties" : {
"id" : {
"type" : "integer"
},
"location" : {
"type" : "geo_point"
},
"name" : {
"type" : "text",
"fields" : {
"raw" : {
"type" : "keyword"
}
}
},
"name_en" : {
"type" : "text",
"fields" : {
"raw" : {
"type" : "keyword"
}
}
}
}
}
}
}
}

商品文档的定义如下:
{
"items" : {
"mappings" : {
"_doc" : {
"properties" : {
"id" : {
"type" : "integer"
},
"name" : {
"type" : "text",
"fields" : {
"raw" : {
"type" : "keyword"
}
}
},
"name_en" : {
"type" : "text",
"fields" : {
"raw" : {
"type" : "keyword"
}
}
}
"shop_id" : {
"type" : "integer"
}
}
}
}
}
}

其中商家文档的 id 代表商家的id, 商品文档的 id 代表商品的id, 商品文档的 shop_id 代表商家的id, 可以通过 shop_id 关联到商家的id
 
我的原始 dsl 大致是这样
GET /shops,items/_search
{
"sort": [
"_score",
{
"_geo_distance": {
"location": {
"lat": "-37.81381100000001",
"lon": "144.95426099999997"
},
"unit": "km",
"order": "asc"
}
}
],
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"geo_distance": {
"distance": "500km",
"location": {
"lat": "-37.81381100000001",
"lon": "144.95426099999997"
}
}
}
]
}
},
"should": [
{
"multi_match": {
"query": "火锅",
"fields": [
"name",
"name_en"
]
}
}
]
}
},
"size": 200,
"from": 1,
"_source": [
"id",
"name"
]
}

因为 dsl 语句中有地理位置 location 的查询,  商家文档匹配的时候没问题,  菜品问题就会出错了.   会提示如下错误:
"failures" : [
{
"shard" : 0,
"index" : "items",
"node" : "FTwntjjSQNeSA9pr4DRwmw",
"reason" : {
"type" : "query_shard_exception",
"reason" : "failed to find geo_point field [location]",
"index_uuid" : "O34wHvxMS0CHWmLw4sU6rg",
"index" : "items"
}
}
]

我的想法是: 先过滤商品名称name 满足条件的记录,  然后获取这些记录的 shop_id,  联合商家名称 name 和距离 location, 过滤掉商品文档, 这样就只剩下满足条件的商家和商品记录了.
但是我不知道能不能通过一个 dsl 实现这个功能, 求教..
 
已邀请:

要回复问题请先登录注册