gpt4 book ai didi

ruby-on-rails - 使用 Elasticsearch/Tire 通过时间表查找开放商店

转载 作者:行者123 更新时间:2023-11-29 02:47:58 30 4
gpt4 key购买 nike

我有模型 Shop,每个模型都与 Timetable 有关系,其中可能包含如下内容:

shop_id: 1, day: 5, open_hour: 7,  open_minutes: 0,  close_hour: 13, close_minute: 30
shop_id: 1, day: 5, open_hour: 14, open_minutes: 30, close_hour: 18, close_minute: 00

当然 Timetable 可以有更优雅的格式,但接下来的问题是:我如何使用 elasticsearch(tire) 找到正在营业的商店?

所有创意都将得到赞赏!谢谢!


找到解决方案:

  1. 为每一天(星期日、星期一、..)创建单独的索引

  2. 每天根据时间表构建完整的分钟数组:

    ((open_hour * 60 + open_minute)..(close_hour * 60 + close_minute)).to_a
  3. 为搜索添加过滤器:

    filter :term, current_day_name => (current_hour * 60 + current_minutes)

这个解决方案同样有效,但它看起来很麻烦,因为如果 Shop 每天工作 8 小时,我创建的数组大小为:8 * 60 = 480 (它被转换为字符串作为索引字段),所以这就是为什么这个问题仍然悬而未决,也许有人会找到更好的解决方案


@Andrei Stefan 回答的轮胎部分:

indexes :open_hours, type: :nested do
indexes :open, type: 'integer'
indexes :close, type: 'integer'
end

open_hours_query = Tire::Search::Query.new do
filtered do
query { all }
filter :range, "open_hours.open" => { lte: current_time }
filter :range, "open_hours.close" => { gte: current_time }
end
end

filter :nested, { path: 'open_hours', query: open_hours_query.to_hash }

最佳答案

我会考虑这样做:

  1. 营业时间和营业时间是 Elasticsearch 中嵌套对象数组的整数值:

示例:商店在 07:00 开门,13:30 关门,然后在第 1 天在 14:30 开门,在 18:00 关门,在 ES 中将转换为:

"shop_name": "Shop 1",
"open_hours": [
{ "open": 420, "close": 810 },
{ "open": 870, "close": 1080 }
]
  1. 一周中的每一天 (1 -> 7) 代表一个值(要添加到分钟数):
Day 1 = addition 0
Day 2 = addition 2000
Day 3 = addition 4000
...
Day 7 = addition 10000

因此,对于每一天都有 2000 的增量,因为每一天最多包含 1440 分钟(24 小时 * 60 分钟)并且能够将一天与单个数字区分开来,这些数字不必相交。

因此,上面的商店在 07:00 开门的示例将被翻译为第 4 天,例如:

"shop_name": "Shop 1",
"open_hours": [
{ "open": 6420, "close": 6810 },
{ "open": 6870, "close": 7080 }
]
  1. 在查询这些文档时,要查找的那一天的那个时间点需要遵循与上述相同的规则。例如,如果您想查看在第 4 天的 13:45“Shop 1”是否开张,您可以搜索 (6000 + 13*60 + 45 = 6825) 分钟。

  2. Elasticsearch 中上述所有内容的映射如下:

{
"mappings": {
"shop" : {
"properties": {
"shop_name" : { "type" : "string" },
"open_hours" : {
"type" : "nested",
"properties": {
"open" : { "type" : "integer" },
"close": { "type" : "integer" }
}
}
}
}
}
}
  1. 测试数据:
POST /shops/shop/_bulk
{"index":{}}
{"shop_name":"Shop 1","open_hours":[{"open":420,"close":810},{"open":870,"close":1080}]}
{"index":{}}
{"shop_name":"Shop 2","open_hours":[{"open":0,"close":500},{"open":1000,"close":1440}]}
{"index":{}}
{"shop_name":"Shop 3","open_hours":[{"open":0,"close":10},{"open":70,"close":450},{"open":900,"close":1050}]}
{"index":{}}
{"shop_name":"Shop 4","open_hours":[{"open":2000,"close":2480}]}
{"index":{}}
{"shop_name":"Shop 5","open_hours":[{"open":2220,"close":2480},{"open":2580,"close":3000},{"open":3100,"close":3440}]}
{"index":{}}
{"shop_name":"Shop 6","open_hours":[{"open":6000,"close":6010},{"open":6700,"close":6900}]}
  1. 查询第 2 天第 2400 分钟(06:40)开设的商店:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "open_hours",
"query": {
"bool": {
"must": [
{
"filtered": {
"filter": {
"range": {
"open_hours.open": {
"lte": 2400
}}}}},
{
"filtered": {
"filter": {
"range": {
"open_hours.close": {
"gte": 2400
}}}}}
]
}}}}
]
}}}

会输出 Shop 4 和 Shop 5:

         "shop_name": "Shop 4",
"open_hours": [
{
"open": 2000,
"close": 2480
}
]

"shop_name": "Shop 5",
"open_hours": [
{
"open": 2220,
"close": 2480
},
{
"open": 2580,
"close": 3000
},
{
"open": 3100,
"close": 3440
}
]

后期编辑:自从我添加此回复以来,Elasticsearch 已经取得了长足的进步,从那以后很多事情都发生了变化,filtered 过滤器(在 bool must 我用过)可以换成bool filter甚至是一个简单的 must。此外,string 不再存在于 6.x 中,因此如果您需要使用分析器或 关键字以某种方式搜索商店名称,则可以使用 text ("shop_name": { "type": "text"},):

{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "open_hours",
"query": {
"bool": {
"filter": [
{
"range": {
"open_hours.open": {
"lte": 2400
}
}
},
{
"range": {
"open_hours.close": {
"gte": 2400
}
}
}
]
}
}
}
}
]
}
}
}

关于ruby-on-rails - 使用 Elasticsearch/Tire 通过时间表查找开放商店,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25823419/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com