【问题标题】:Query based on calculated fields with Mongoid基于 Mongoid 计算字段的查询
【发布时间】:2012-07-12 12:14:26
【问题描述】:

我想在模型 Invoice 中实现一个范围 overdue 以返回所有超过日期的发票,直到必须付款。我有 invoice_date, :type => Datedays_for_payment, :type => Integer 字段。

在我之前基于 ActiveRecord 构建的版本中,我可以使用查询

Invoice.where("invoice_date + days_for_payment < ?", Date.today)

此查询在 DB 端进行计算。

有没有办法用 Mongoid 完成同样的事情?或者有谁知道一个好的解决方法(proc、lambda 等)?

我使用 mongoid '2.4.12'

【问题讨论】:

    标签: ruby-on-rails mongodb mongoid


    【解决方案1】:

    自己找到了答案。使用前缀 this.* 我可以引用这些字段。我可以使用 JavaScript 函数。 MongoDB 变得越来越酷!

    所以这是我的解决方案:

    class Invoice
      include Mongoid::Document
      field :invoice_date, :type => Date
      field :days_for_payment, :type => Integer
      ...
    
      scope :overdue, where("(Math.round(this.invoice_date.getTime() / 1000) + (this.days_for_payment * 24 * 3600)) < #{Time.now.to_i}")
    
      ...
    end
    

    在 js 中创建时间戳的工作方式不同。所以我不得不去掉最后三个数字并将它们四舍五入。 如果有人知道更优雅的方式,请告诉我。

    剩下的唯一问题是,我无法将 Date 对象存储到 MongoDB。它总是告诉我必须使用Time。我认为我最好将 mongoid 升级到 3.0.1。

    【讨论】:

    • 在 JS 中处理日期没有更优雅的方法了。自纪元以来,一切都以毫秒为单位。但是,在您的特定情况下,当您存储 :invoice_date:days_for_payment 时,您可以使用存储 before_savebefore_validationbefore_save 回调:这将更有效,因为您可以正常查询,这意味着一个索引(以及范围查询)。
    【解决方案2】:

    我不确定mongoid,如果你直接查询mongodb你可以使用$where operator。不推荐,因为它不使用索引。如果您有另一个条件将记录过滤到一个小集合,那么您可以使用 $where 进一步过滤它。

    【讨论】:

    • 谢谢,但我想我自己找到了解决方案! Here...
    猜你喜欢
    • 2016-04-12
    • 2011-05-13
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    相关资源
    最近更新 更多