簡體   English   中英

Mongoid Moped查詢未返回與MongoDB Shell相同的查詢

[英]Mongoid Moped query not returning the same as the MongoDB shell

使用Mongoid 3.1.5和MongoDB 2.4.9創建查詢時,我從Mongoid / Moped查詢中得到的結果與在等效MongoDB查詢中得到的結果不同。

更新添加的Mongoid查詢它的長期查詢為:

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_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}

這意味着在不存在該字段的地方返回結果

{"avg_rating"=>nil}

這限制了該字段存在但設置為nil的結果。

請參閱以下文檔: http : //docs.mongodb.org/manual/reference/operator/query/exists/

如果為true,則$ exists匹配包含該字段的文檔,包括該字段值為null的文檔。 如果為false,則查詢僅返回不包含該字段的文檔。

除了exist null之間的差異之外,您還可能遇到時區問題。

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的第二個參數以簡化操作。 或使用{ _id: true }並放下count()以減少混亂。

解決我和tirdadc指出的問題,看看在兩種情況下您是否都得到相同的結果。 如果您不這樣做,則開始逐個構建兩個查詢,直到它們產生不同的結果,並且您將知道問題出在哪里。 不要忘記從一開始就包括排序選項,並比較返回的文檔ID,而不僅僅是計數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM