【问题标题】:RoR3+Mongoid: How to compare fields of collection/table when querying?RoR3+Mongoid:查询时如何比较集合/表的字段?
【发布时间】:2011-10-18 18:06:37
【问题描述】:

我有一个结构,它同时具有 :id 和 :group_id 字段。我希望检索 :id 等于 :group_id 的所有数据。

我目前正在使用 mongoid,但我认为该操作的完成方式与使用 Rails3 的 ActiveRecord 时的操作方式相同。

无论如何。我试图使用Message.where(:group_id => :id),它应该返回,例如:=> #<Message _id: 4e38aa132748440a7e00007d, group_id: BSON::ObjectId('4e38aa132748440a7e00007d')>。但它根本不起作用(似乎它真的不应该起作用,但它应该怎么做呢?)

如何查询 mongoid(或活动记录)以仅获取 :id 等于 :group_id 的消息?

编辑: 只是为了表明这些值确实完全相同:

ruby-1.9.2-p180 :088 > Message.first.id
=> BSON::ObjectId('4e38aa132748440a7e00007d')
ruby-1.9.2-p180 :089 > Message.first.group_id
=> BSON::ObjectId('4e38aa132748440a7e00007d')

编辑2: 这些不起作用(它们至少有一条匹配的消息(上面的示例)):

ruby-1.9.2-p180 :091 > Message.where("group_id = id").count
 => 0 
ruby-1.9.2-p180 :092 > Message.where("group_id == id").count
 => 0 

编辑3: 以下是应返回的消息示例:http://cl.ly/3q1r20421S3P1921101D

编辑4: 另一个奇怪的地方:

ruby-1.9.2-p180 :034 >  Message.where("this._id = this.group_id").each { 
|m| puts "#{m.id} = #{m.group_id}" }
4e38aa132748440a7e00007d = 4e38aa132748440a7e00007d
4e38aa132748440a7e00007e = 4e38aa132748440a7e00007d
4e38aa562748440a7e000084 = 4e38aa562748440a7e000084
4e38aa562748440a7e000085 = 4e38aa562748440a7e000084
4e38ac312748440a7e000095 = 4e38ac312748440a7e000095
4e38ac312748440a7e000096 = 4e38ac312748440a7e000095
4e38ac312748440a7e000097 = 4e38ac312748440a7e000095

为什么它返回这些值,即使在某些情况下它们不相等?啊啊啊啊

EDIT5:另一个奇怪的地方和一个不确定的小结论:

ruby-1.9.2-p180 :090 >  Message.where("this.read == this.sender_deleted").each { 
|m| puts "#{m.read.to_s},#{m.sender_deleted.to_s}" }
true,true
false,false
false,false
false,false
false,false

我的查询使用布尔值!因此,它似乎不仅仅适用于 BSON::ObjectId() 对象比较(我也无法通过执行 Message.where(:id => Message.first.id [编辑:我设法通过使用 :_id 而不是 :id 来检索消息,但这确实不能帮助我解决剩下的问题])。如何在同一个对象上比较这些该死的标识符?我真的需要,而且恐怕没有优雅的选择(将那些完全相同的 ID 存储为字符串太奇怪了,请不要建议这样做:/)最后,这似乎是 Mongoid 的一个特定问题

obs.:我尝试了所有想到的组合,关于 id vs. _id and = vs. ==。是否有任何类似哈希的查询来完成我所需要的?使用类似 .where(:_id => :group_id) 的东西(但不是那个,我的意思是 :group_id 值,而不是 :group_id 符号)。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord mongodb mongoid


    【解决方案1】:

    Mongoid 最终使用的是 MongoDB,所以在 mongodb 中做不到的任何事情都不能使用 mongoid 来完成。 mongodb 目前不支持您所说的特定用例。

    您不能根据字段查询字段,您必须提供文字值以进行查询。我在 Mongodb Issue Tracker 上看到了一个支持此问题的问题,但现在找不到。

    您提到的布尔值查询可能只是巧合。这也不应该按预期工作。

    更新

    可以使用 $where 子句比较 mongodb 中的字段。

    【讨论】:

    • 啊,确实是这样。我发现了另一个问题:cl.ly/0v1D2I12090y15431937 也说明了这一点。它说您可以使用 javascript 来实现,但是,相对而言速度非常慢,我想我会重新考虑替代解决方案。如果有人知道比较集合中的字段的方法,请报告! :) 感谢您的回复。
    • @Fernando 对事实错误感到抱歉,您可以使用 $where 子句比较字段。参考:mongodb.org/display/DOCS/…
    • 感谢您记住我的问题并返回这里,非常感谢!
    【解决方案2】:

    试试这个:

    Message.where("this.group_id == this.id")
    

    【讨论】:

    • 我不知道为什么,但这也没有用。这似乎是比较 ObjectIds 特有的问题,但我确实需要。如果我确实喜欢这个,但使用布尔值,例如,它工作得很好。不使用 ObjectIds..
    • 抱歉,等号 javascript 运算符拼写错误(写 = 而不是 ==),现在试试。我已经更新了答案。
    • 它也不起作用,看起来很奇怪。但是,如果我将它与非 ObjectId 字段一起使用,它似乎可以工作。 > Message.where("this.id == this.group_id").count => 0 > Message.where("this._id == this.group_id").count => 0 - 那些不应该返回 0。
    【解决方案3】:

    你在 Mongoid 的 where 方法中遗漏了 '$where'

    这对我有用:

    Message.where('$where' => 'this.group_id == this.id')
    

    【讨论】:

      【解决方案4】:
      Message.where("group_id = id")
      

      【讨论】:

        猜你喜欢
        • 2011-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-04
        • 2015-01-31
        • 1970-01-01
        • 2012-02-08
        • 2018-06-24
        相关资源
        最近更新 更多