草庐IT

javascript - 获取一周数的所有对象

coder 2023-11-06 原文

我需要获取 MongoDB 中所有记录的周范围列表。当我点击一个周范围时,它将只显示该周范围的记录。单击周范围会发送周 ID(比方说 42,即 2015 年的第 42 周),应该会得到这些结果。

问题:如何查询给定周数和年份的一组记录?这应该有效,对吧?

架构:

var orderSchema = mongoose.Schema({
        date: Date, //ISO date
        request: {
            headers : {
            ...

首先:获取所有对象的所有周 ID:

    var query = Order.aggregate(
        [
            {
                $project:
                {
                    week:
                    {
                        $week: '$date'
                    }
                }
            },
            {
                $group:
                {
                    _id: null,
                    distinctDate:
                    {
                        $addToSet:
                        {
                            week: '$week'
                        }
                    }
                }
            }
        ]
    );

结果:

distinctDate: Array[35]
    0: Object
       week: 40
    1: Object
       week: 37
       ...

使用 MomentJS 转换为星期范围并显示:

    data.forEach(function(v, k) {
        $scope.weekRanges.push(getWeekRange(v.week));
    });

    function getWeekRange(weekNum) {

        var monday = moment().day("Monday").isoWeek(weekNum).format('MM-DD-YYYY');
        var sunday = moment().day("Sunday").isoWeek(weekNum).format('MM-DD-YYYY');
        ...

输出:

Week 
10-12-2015 to 10-18-2015 //week ID 42
10-05-2015 to 10-11-2015 //week ID 41
09-28-2015 to 10-04-2015 ...
...

其次:点击周范围并获取 Objects Per Week ID:

var year = 2015;
var weekID = weekParamID; //42

    if (!Order) {
        Order = mongoose.model('Order', orderSchema());
    }

    var query = Order.aggregate(
        {
            $project:
            {
                cust_ID : '$request.headers.custID',
                cost : '$response.body.pricing.cost',
                year :
                {
                    $year:  '$date'
                },
                month :
                {
                    $month: '$date'
                },
                week:
                {
                    $week: '$date'
                },
                day:
                {
                    $dayOfMonth: '$date'
                }
            }
        },
        {
            $match:
            {
                year : year, //2015
                week : weekID //42
            }
        }
    );

如果我点击 Week Range 10-12-2015 to 10-18-2015(周 ID 42),我会得到日期超出范围 (10-19-2015) 的结果:

10-19-2015      Order info  
10-18-2015      Order info
10-19-2015      Order info

使用 MongoDB 命令行:

db.mycollection.aggregate({ $project: { week: { $week: '$date' }, day: { $dayOfMonth: '$date' } }  }, { $match: { week: 42 } }

结果:

{ "_id" : "1bd482f6759b", "week" : 42, "day" : 19 } //shouldn't exceed week range
{ "_id" : "b3d38759", "week" : 42, "day" : 19 }

编辑:更新

因此与 MongoDB ISO 周(从星期日开始)和 Moment JS ISO(从星期一开始)存在差异。

This SO post建议从查询中减去日期,以便 Mongo 日期从星期一开始:

{ 
$project: 
  {
    week: { $week: [ "$datetime" ] },
    dayOfWeek:{$dayOfWeek:["$datetime"]}}
  },
{
$project:
 {
  week:{$cond:[{$eq:["$dayOfWeek",1]},{$subtract:["$week",1]},'$week']}
 }
}

我用我的查询实现了这个,但现在它没有返回我需要的两个字段:

            cust_ID : '$request.headers.custID',
            cost : '$response.body.pricing.cost'

查询:

 db.mycollection.aggregate(
        {
            $project:
            {
                cust_ID : '$request.headers.custID',
                cost : '$response.body.pricing.cost',
                week:
                {
                    $week: ['$date']
                },
                dayOfWeek:
                {
                    $dayOfWeek: ['$date']
                }
            }
        },
        {
            $project:
            {
                week: {
                    $cond: [
                        {
                            $eq: [
                                "$dayOfWeek", 1
                            ]
                        },
                        {
                            $subtract: [
                                "$week", 1
                            ]
                        }, '$week'
                    ]
                }
            }
        },
        {
            $match:
            {
                week : 42
            }
        }
    );

结果:

{ "_id" : "387e2", "week" : 42 }
{ "_id" : "ef269f6341", "week" : 42 }
{ "_id" : "17482f6759b", "week" : 42 }
{ "_id" : "7123d38759", "week" : 42 }
{ "_id" : "ff89b1fb", "week" : 42 }

它没有返回我在 $project 中指定的字段集

最佳答案

MongoDB $week 运算符认为周从星期日开始,see docs :

Weeks begin on Sundays, and week 1 begins with the first Sunday of the year... This behavior is the same as the “%U” operator to the strftime standard library function.

Moment.JS 的 isoWeekday() 使用 ISO 周,认为周从星期一开始。它的不同之处还在于,它认为第 1 周是第一个星期四。

这种差异可以解释您所看到的行为。

例如如果我将此文档保存在星期一的 MongoDB 中:

db.test.save({ "date" : new ISODate("2015-10-19T10:10:10Z")  })

然后运行上面的聚合查询,我得到第 42 周。

但是如果我运行以下命令:

console.log(moment().day("Monday").isoWeek(42))

我得到以下日期,这不是我最初保存在 MongoDB 中的日期,即使它是 MongoDB 报告的一周中的星期一。

Mon Oct 12 2015

我想如何解决它取决于您需要的周定义。

如果您对 MongoDB $week 定义感到满意,可能很容易找到/编写一个替代实现来将周数转换为相应的日期。这是一个向 Moment.js 添加 strftime 支持的库:

https://github.com/benjaminoakes/moment-strftime

如果要使用ISO格式,就比较复杂了。根据您上面的编辑,您需要考虑周开始差异。但是您还需要考虑年初差异的周数。这种差异意味着 strftime 周数可以有第 0 周,而 ISO 始终从第 1 周开始。对于 2015 年,您似乎需要在 strftime 周上添加 1 周才能获得 ISO 周,并计算该周开始日,但这通常不可靠。

关于javascript - 获取一周数的所有对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33223200/

有关javascript - 获取一周数的所有对象的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  5. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  6. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  7. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  8. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  9. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  10. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

随机推荐