将数据存储在ElasticSearch中并过滤建议

时间:2019-05-28 13:54:34

标签: elasticsearch

我在如何最好地在Elasticsearch中存储数据方面遇到问题。我希望它能够以将返回给用户的确切格式存储数据。我也不想在从Elasticsearch获得结果之后进行任何处理。我将汇总查询以基于可能的过滤器获取数据计数。

我有一个API端点,该端点使用户可以按名称搜索公司并以以下格式返回结果:

{
    "company": {
        "name": "KFC",
        "status": "running",
        "Cuisine": "Kentucky Fried Chicken"
    },
    "mainRestaurant": {
        "location": {
            "road": "main road",
            "city": "New York City",
            "state": "New York",
            "country": "USA"
        },
        "status": "running",
        "type": "Flagship restaurant"
    }
}

此数据从公司数据库和餐馆数据库一起推送。根据以下条件从餐馆列表中选择mainRestaurant: *如果有旗舰餐厅,请使用它。 *如果没有,则使用数据库中找到的第一个餐厅,其中有一个名为important的特定标志设置为true。 *如果没有,请选择您在数据库中找到的第一个。

所有公司都将拥有一个旗舰餐厅,因此,当没有应用位置过滤器时,上述逻辑就不会成为问题,因为mainRestaurant将始终是公司的旗舰餐厅。但是,如果传入一个位置,则很可能我们将继续进行逻辑的后续部分。

我想要做的是从Elasticsearch为每个公司的每个公司获取单个结果,而我的计划是为每个公司的每个地点添加一个结果。因此,该索引只会在每个位置保存肯德基(以及其他公司)的主要餐厅。因此,对于纽约,它将存储以上结果,对于伦敦,它将存储如下结果:

{
    "company": {
        "name": "KFC",
        "status": "running",
        "Cuisine": "Kentucky Fried Chicken"
    },
    "mainRestaurant": {
        "location": {
            "road": "main road",
            "city": "London",
            "state": "England",
            "country": "UK"
        },
        "status": "running",
        "type": "important restaurant"
    }
}

这里的问题是,Elasticsearch中现在每个公司都有多个结果,而没有一种简单的方法可以在单个查询中获取最佳结果。为此,我的解决方案是使用一些元数据在对象周围添加包装器。因此,对于第一个结果(肯德基旗舰店):

{
    "bestRestaurantIn": ["*", "USA", "New York", "New York City"],
    "result": {
        ... data ...
    }
}

对于伦敦重要的餐厅,它看起来像这样:

{
    "bestRestaurantIn": ["UK", "England", "London"],
    "result": {
        ... data ...
    }
}

对于曼彻斯特最好的餐厅,它是这样的:

{
    "bestRestaurantIn": ["Manchester"],
    "result": {
        ... data ...
    }
}

因此,如果您不传递位置,则可以在存在*的地方添加一个term子句,以便对于“肯德基”公司,在bestRestaurantIn中只有带有*的那个搜索时将返回该字段。如果您将“曼彻斯特”作为位置过滤器传递,它将仅获得曼彻斯特的肯德基,因为在曼彻斯特,肯德基只有一个结果。

以下是在名称中搜索“ kf”时的一些示例。它应该给出:

  • 位置过滤器为空时->应该返回纽约的旗舰餐厅,因为它是肯德基的主要主餐厅
  • 当位置过滤器是“纽约”时->纽约的旗舰餐厅,因为它是纽约肯德基的主要餐厅。
  • 当位置过滤器是曼彻斯特->曼彻斯特的肯德基应返回。

因此,如果还有一家名为“ KFB”的餐厅(假设Elasticsearch中没有其他名称与搜索“ KF”匹配的结果),那么每个位置最多只能返回2个结果,在某些情况下如果公司在特定位置没有餐厅,则为1或0。

上述解决方案可以正常工作。然而,当添加更多过滤器时,这成为一个问题。餐厅数据库中的每个餐厅都有一个状态。可以是“正在运行”或“关闭”。这意味着我们将需要为每个位置的每个公司添加一个“正在运行的”餐厅和一个“关闭”餐厅(如果有)。我们还需要在包装器中添加一个标志,例如“ isBestWithNoFilters”,它可能是“正在运行的”餐厅。

我的问题是,这根本无法很好地扩展。如果我需要在餐厅级别添加多个,那么这将变得异常复杂。有没有我应该遵循的模式?

很抱歉,很长的帖子。我希望我已经说清楚了!

0 个答案:

没有答案