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

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 使用Elasticsearch / Tire通过时间表查找开放式商店前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有模型商店每个都与时间表有关系,可能包含以下内容
  1. shop_id: 1,day: 5,open_hour: 7,open_minutes: 0,close_hour: 13,close_minute: 30
  2. shop_id: 1,open_hour: 14,open_minutes: 30,close_hour: 18,close_minute: 00

当然,时间表可以有更优雅的格式,但问题是下一个:如何使用elasticsearch(轮胎)我可以找到开放的商店吗?

所有的想法都会被贬低!谢谢!

找到解决方

>为每一天创建单独的索引(星期日,星期一,…)
>每天从时间表中构建完整的分钟数:

  1. ((open_hour * 60 + open_minute)..(close_hour * 60 + close_minute)).to_a

>添加过滤器进行搜索

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

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

@Andrei Stefan的轮胎部分回答:

  1. indexes :open_hours,type: :nested do
  2. indexes :open,type: 'integer'
  3. indexes :close,type: 'integer'
  4. end
  5.  
  6. open_hours_query = Tire::Search::Query.new do
  7. filtered do
  8. query { all }
  9. filter :range,"open_hours.open" => { lte: current_time }
  10. filter :range,"open_hours.close" => { gte: current_time }
  11. end
  12. end
  13.  
  14. filter :nested,{ path: 'open_hours',query: open_hours_query.to_hash }

解决方法

我会考虑这样做:

>开始和结束时间是Elasticsearch中嵌套对象数组的整数值:

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

  1. "shop_name": "Shop 1","open_hours": [
  2. { "open": 420,"close": 810 },{ "open": 870,"close": 1080 }
  3. ]

>一周中的每一天(1 – > 7)表示一个值(要添加到分钟数):

  1. Day 1 = addition 0
  2. Day 2 = addition 2000
  3. Day 3 = addition 4000
  4. ...
  5. Day 7 = addition 10000

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

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

  1. "shop_name": "Shop 1","open_hours": [
  2. { "open": 6420,"close": 6810 },{ "open": 6870,"close": 7080 }
  3. ]

>查询这些文档时,您想要搜索的那一天需要遵守与上述相同的规则.例如,如果您想在第4天13:45看到“商店1”打开,您将搜索(6000 13 * 60 45 = 6825)分钟.
> Elasticsearch中上面所有内容的映射都是这样的:

  1. {
  2. "mappings": {
  3. "shop" : {
  4. "properties": {
  5. "shop_name" : { "type" : "string" },"open_hours" : {
  6. "type" : "nested","properties": {
  7. "open" : { "type" : "integer" },"close": { "type" : "integer" }
  8. }
  9. }
  10. }
  11. }
  12. }
  13. }

>测试数据:

  1. POST /shops/shop/_bulk
  2. {"index":{}}
  3. {"shop_name":"Shop 1","open_hours":[{"open":420,"close":810},{"open":870,"close":1080}]}
  4. {"index":{}}
  5. {"shop_name":"Shop 2","open_hours":[{"open":0,"close":500},{"open":1000,"close":1440}]}
  6. {"index":{}}
  7. {"shop_name":"Shop 3","close":10},{"open":70,"close":450},{"open":900,"close":1050}]}
  8. {"index":{}}
  9. {"shop_name":"Shop 4","open_hours":[{"open":2000,"close":2480}]}
  10. {"index":{}}
  11. {"shop_name":"Shop 5","open_hours":[{"open":2220,"close":2480},{"open":2580,"close":3000},{"open":3100,"close":3440}]}
  12. {"index":{}}
  13. {"shop_name":"Shop 6","open_hours":[{"open":6000,"close":6010},{"open":6700,"close":6900}]}

>在当天(06:40)的第2400分钟查询第2天开设的商店:

  1. {
  2. "query": {
  3. "bool": {
  4. "must": [
  5. {
  6. "nested": {
  7. "path": "open_hours","query": {
  8. "bool": {
  9. "must": [
  10. {
  11. "filtered": {
  12. "filter": {
  13. "range": {
  14. "open_hours.open": {
  15. "lte": 2400
  16. }}}}},{
  17. "filtered": {
  18. "filter": {
  19. "range": {
  20. "open_hours.close": {
  21. "gte": 2400
  22. }}}}}
  23. ]
  24. }}}}
  25. ]
  26. }}}

输出Shop 4和Shop 5:

  1. "shop_name": "Shop 4","open_hours": [
  2. {
  3. "open": 2000,"close": 2480
  4. }
  5. ]
  6.  
  7. "shop_name": "Shop 5","open_hours": [
  8. {
  9. "open": 2220,"close": 2480
  10. },{
  11. "open": 2580,"close": 3000
  12. },{
  13. "open": 3100,"close": 3440
  14. }
  15. ]

LATER EDIT:自从我添加了这个回复并且自那时以来许多事情发生了变化以来,Elasticsearch已经采用了一种方式,过滤后的过滤器(在我必须使用的bool的上下文中)可以被bool filter或简单的必须替换.此外,该字符串在6.x中不再存在,因此如果您需要使用分析器或关键字(“shop_name”:{“type”:“text”},)按商店名称搜索,则可以使用文本:

  1. {
  2. "query": {
  3. "bool": {
  4. "must": [
  5. {
  6. "nested": {
  7. "path": "open_hours","query": {
  8. "bool": {
  9. "filter": [
  10. {
  11. "range": {
  12. "open_hours.open": {
  13. "lte": 2400
  14. }
  15. }
  16. },{
  17. "range": {
  18. "open_hours.close": {
  19. "gte": 2400
  20. }
  21. }
  22. }
  23. ]
  24. }
  25. }
  26. }
  27. }
  28. ]
  29. }
  30. }
  31. }

猜你在找的Ruby相关文章