MongoDB - 营业时间,按当天排序

Posted

技术标签:

【中文标题】MongoDB - 营业时间,按当天排序【英文标题】:MongoDB - Business hours, order by current day 【发布时间】:2020-03-21 11:49:43 【问题描述】:

我正在尝试重新创建位置列表上显示的 Google“营业时间”下拉菜单。

营业时间数组如下所示:

[
    id: 5d991d1208ac396803a992ee, day: 'sunday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992ef, day: 'monday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eg, day: 'tuesday', open: 560, close: 1050,
    id: 45d991d1208ac396803a992e, day: 'wednesday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eh, day: 'thursday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eI, day: 'friday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eG, day: 'saturday', open: 560, close: 1050,
]

所以,如果今天是星期二,我想返回一个这样的排序数组:

[
    id: 5d991d1208ac396803a992eg, day: 'tuesday', open: 560, close: 1050,
    id: 45d991d1208ac396803a992e, day: 'wednesday', open: 560, close: 1050,
    ....
]

我正在使用猫鼬和 MongoDB。

更新 ID 由 MongoDB 生成,因此我无法对其进行排序或匹配。

【问题讨论】:

为什么你不用$sortid 请参阅更新。谢谢 将您的模型设计为将当天的索引添加为索引或字段以允许排序不是更容易吗?您不必总是使用 mongoID。这是这样一种情况。一周只有7天。但无论如何,如果你不能,那么是的,使用 Seoung Ho Jeoung 的解决方案先对星期几进行排序,然后切片和连接 【参考方案1】:

使用扩展运算符进行切片和连接:

// needs the day of the week
// starting from Sunday as 0 and saturday as 6 since getDay()
// starts from 0
const currentDay = new Date().getDay() // 0, 1, 2, 3, 4, 5,  or 6

// here's your function

const getSortedArray = (arr) => [
  ...arr.slice(currentDay),
  ...arr.slice(0, currentDay)
]

// example

const days = [
    id: '5d991d1208ac396803a992ee',
    day: 'sunday',
    open: 560,
    close: 1050
  ,
  
    id: '5d991d1208ac396803a992ef',
    day: 'monday',
    open: 560,
    close: 1050
  ,
  
    id: '5d991d1208ac396803a992eg',
    day: 'tuesday',
    open: 560,
    close: 1050
  ,
  
    id: '45d991d1208ac396803a992e',
    day: 'wednesday',
    open: 560,
    close: 1050
  ,
  
    id: '5d991d1208ac396803a992eh',
    day: 'thursday',
    open: 560,
    close: 1050
  ,
  
    id: '5d991d1208ac396803a992eI',
    day: 'friday',
    open: 560,
    close: 1050
  ,
  
    id: '5d991d1208ac396803a992eG',
    day: 'saturday',
    open: 560,
    close: 1050
  ,
]

// ensure order of days
const daysSorted = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']
  .map(day => days.filter(el => el.day === day)[0])

console.log(getSortedArray(daysSorted))

【讨论】:

【参考方案2】:

你可以使用下面的聚合

const day = "tuesday"

db.collection.aggregate([
   "$group": 
    "_id": null,
    "data":  "$push": "$$ROOT" 
  ,
   "$project": 
    "data": 1,
    "days": 
      "$concatArrays": [
        
          "$setDifference": [
            "$data.day",
            
              "$slice": [
                "$data.day",
                 "$indexOfArray": ["$data.day", day]   //Here you can replace the day with the current one
              ]
            
          ]
        ,
        
          "$slice": [
            "$data.day",
             "$indexOfArray": ["$data.day", day]   //Here you can replace the day with the current one
          ]
        
      ]
    
  ,
   "$unwind": "$data" ,
   "$addFields": 
    "order": 
      "$indexOfArray": ["$days", "$data.day"]
    
  ,
   "$sort":  "order": 1 ,
   "$replaceRoot":  "newRoot": "$data" 
])

MongoPlayground

【讨论】:

【参考方案3】:

首先从mongodb数据中排序营业时间,然后使用Emmanuel N K的解决方案

// needs the day of the week
const currentDay = new Date().getDay() // 1, 2, 3, 4, 5, 6 or  7

// here's your function
// subtract 1 from currentday since array indices start at zero

const getSortedArray= (arr) => [
    ...arr.slice(currentDay - 1), 
    ...arr.slice(0, currentDay - 1)
]

const getIntFromDay = (day) => 
    return ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday','saturday'].indexOf(day)


// example

const days = [
    id: 5d991d1208ac396803a992ee, day: 'sunday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992ef, day: 'monday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eg, day: 'tuesday', open: 560, close: 1050,
    id: 45d991d1208ac396803a992e, day: 'wednesday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eh, day: 'thursday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eI, day: 'friday', open: 560, close: 1050,
    id: 5d991d1208ac396803a992eG, day: 'saturday', open: 560, close: 1050,
]

sortedDays = days.sort((a, b) => 
    if(getIntFromDay(a.day) > getIntFromDay(b.day))
        return 1
    else
        return -1
)


console.log(getSortedArray(sortedDays))

【讨论】:

以上是关于MongoDB - 营业时间,按当天排序的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 条件查询和排序

mongoDB统计数据--mapReduce实现

从 MongoDB 排序规则获取不需要的输出

mongodb 分组统计: 按deviceId、tenant分组,统计总记录条数、求和workload

mongodb Aggregation聚合操作之$sort

在 Mongo Laravel 中按价格排序