Ruby on rails Mongoid Moped查询返回的结果与MongoDB shell不同

Ruby on rails Mongoid Moped查询返回的结果与MongoDB shell不同,ruby-on-rails,mongodb,mongoid,mongoid3,moped,Ruby On Rails,Mongodb,Mongoid,Mongoid3,Moped,使用Mongoid 3.1.5和MongoDB 2.4.9创建查询时,我从Mongoid/Moped查询中得到的结果与等效的MongoDB查询不同 更新添加的Mongoid查询 查询的long for为: return Video.order_by(release_date: :desc, avg_rating: :desc, title: :asc) .where( :viewable => true, :release_date.lte => start_at_date, :re

使用Mongoid 3.1.5和MongoDB 2.4.9创建查询时,我从Mongoid/Moped查询中得到的结果与等效的MongoDB查询不同

更新添加的Mongoid查询 查询的long for为:

return Video.order_by(release_date: :desc, avg_rating: :desc, title: :asc)
.where( :viewable => true, :release_date.lte => start_at_date, :release_date.gte =>
start_date, :categories.in => genre_filters).any_of({:avg_rating.gt => 1},
{:avg_rating => nil}).skip(skip*POSTERS_PER_ROW).limit(limit*POSTERS_PER_ROW)
.only(:_id, :poster_large_thumb, :title, :similar_as_string, :release_date, :avg_rating)
除了
genre\u filters
导致一次只能找到一个对象之外,这个查询对我抛出的所有内容都能正常工作

我得到以下控制台输出,描述Moped查询:

MOPED: 127.0.0.1:27017 QUERY        database=guide_development collection=videos 
selector={"$query"=>{"viewable"=>true, "release_date"=>{"$lte"=>2014-03-27 00:00:00 UTC,
"$gte"=>1850-01-01 00:00:00 UTC}, "categories"=>{"$in"=>["Netflix"]}, 
"$or"=>[{"avg_rating"=>{"$gt"=>1}}, {"avg_rating"=>nil}]}, "$orderby"=>
{"release_date"=>-1, "avg_rating"=>-1, "title"=>1}} 
flags=[:slave_ok] limit=60 skip=0 batch_size=nil fields={"_id"=>1,
"poster_large_thumb"=>1, "title"=>1, "similar_as_string"=>1, "release_date"=>1,
"avg_rating"=>1} (198.0939ms)
这不会返回任何结果——这不是我所期望的

过了一段时间,我提出了以下MongoDB shell查询,应该是等效的:

var start = new Date(2014, 3, 27);
var end - new Date(1850,1,1);

db.videos.find({
    viewable: true, release_date: {
    $lte: start, $gte: end
    }, 
    categories:{
        $in: ["Netflix"]
    }, $or: [ {avg_rating: {$gt: 1}}, {avg_rating: {$exists: false}}],
},{
    _id: 1,
    poster_large_thumb: 1,
    title: 1,
    similar_as_string: 1,
    release_date: 1,
    average_rating: 1
}).sort({release_date: -1, avg_rating: -1, title:1}).skip(0).limit(60).count()
在MongoDB shell中给出一个结果,这是它应该找到的一个对象


有什么想法吗?一个对象的结果是否会导致Mongoid出现问题?

我认为以下两者之间有区别:

avg_rating: {$exists: false}
这意味着返回字段不存在的结果

它限制了字段存在但设置为nil的结果

请参见此处的文档:

如果为true,$exists与包含 字段,包括字段值为空的文档如果 如果为false,则查询仅返回不包含 字段。

此外,你可能有时区问题

Rails和Mongoid将为您将时间戳转换为UTC,您可以在Moped日志中看到这一点:

"release_date"=>{"$lte"=>2014-03-27 00:00:00 UTC, "$gte"=>1850-01-01 00:00:00 UTC}
Mongoid使用2014-03-27T00:00:00Z和1850-01-01T00:00:00Z作为时间戳,因此您可以使用00:00:00(UTC)作为时间组件。MongoDB内部的时间戳也将以UTC为单位

但是,当MongoDB shell将
2014-03-27
转换为时间戳时,它将使用当前有效的任何时区:

> new Date(2014, 3, 27)
ISODate("2014-04-27T07:00:00Z")
注意07:00:00Z。这七个小时来自我的PDT时区(GMT-0700)。您应该在MongoDB shell中使用
ISODate
便利功能,因此:

> ISODate('2014-03-27')
ISODate("2014-03-27T00:00:00Z")
> ISODate('1850-01-01')
ISODate("1850-01-01T00:00:00Z")
确保你的时区正确

此外,由于您只查看计数,因此可以省略MongoDB shell中的
find
的第二个参数,以简化操作。或者使用
{u id:true}
并删除
count()
以减少混乱


修复和我指出的问题,看看在这两种情况下是否得到相同的结果。如果没有,则开始逐段构建这两个查询,直到它们产生不同的结果,然后您就会知道问题所在。不要忘记从一开始就包括排序选项,并比较返回的文档ID,而不仅仅是计数。

整个场景都在我的开发机器上运行,因此我相信时区不是问题。优化查询是值得赞赏的,但不是问题所在。我可能没有最佳的查询,但为什么我从一个查询中得到结果,而在同一台机器上,同一个数据库却没有得到任何结果。不要相信,验证。新日期(2014年3月27日)在MongoDB shell中说明了什么?切换到
ISODate
会改变什么吗?我有其他order\u by查询以不使用发布日期的方式进行排序,它们给出相同的结果,没有返回数据。我刚开始发布日期排序,所以现在必须坚持。例如,有一个不指定日期范围的按标题排序查询,当类别=[“Netflix”]时返回0,当类别=[“Horror”,“Netflix”]时返回一个bunch。由于单个Netflix电影是恐怖电影,因此在指定categories=[“horror”,“Netflix”]的任何查询中都会返回它。我尝试了一组batchSize值,请注意,Moped显示batchSize=nil。但这对结果没有任何影响。shell查询总是有效的,Mongoid永远不会有效。你确定Mongoid和MongoDB shell正在与同一个数据库通信吗?好的,shell中的moped{“avg_rating”=>nil}等价物是什么?我只是想弄明白为什么最初用Ruby编写的查询不起作用。如果我向Netflix添加另一个类别,比如Mongoid中的“恐怖”,则会使用另一个类别创建相同的Moped查询,所有查询都返回一堆文档。唯一奇怪的是,只有一个文档有Netflix,或者查询中只有一个类别。请提供示例文档好吗?
> ISODate('2014-03-27')
ISODate("2014-03-27T00:00:00Z")
> ISODate('1850-01-01')
ISODate("1850-01-01T00:00:00Z")