1

Mongoid 3.1.5 と MongoDB 2.4.9 を使用してクエリを作成する 同等の MongoDB クエリから行う Mongoid/Moped クエリとは異なる結果が得られます。

更新が追加された 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このクエリは、オブジェクトが 1 つしか見つからない場合を除いて、私が投げたすべてのものに対して正しく機能します。

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 シェル クエリを思いつきました。

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 シェルで 1 つの結果を返します。これが 1 つのオブジェクトを見つける必要があります。

何か案は?1つのオブジェクトの結果がMongoidで問題を引き起こしますか?

4

2 に答える 2

2

次のような違いがあると思います。

avg_rating: {$exists: false}

これは、フィールドが存在しない場合に結果を返すことを意味します

{"avg_rating"=>nil}

これは、フィールドが存在するが nil に設定されている結果に限定されます。

ここのドキュメントを参照してください: http://docs.mongodb.org/manual/reference/operator/query/exists/

が true の場合、$exists は、フィールド値が null であるドキュメントを含む、フィールドを含むドキュメントと一致します。が false の場合、クエリはフィールドを含まないドキュメントのみを返します。

于 2014-03-27T02:16:15.553 に答える
0

存在とisの違いに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 になります。

2014-03-27ただし、MongoDB シェルは、タイムスタンプに変換するときに現在有効なタイム ゾーンを使用します。

> new Date(2014, 3, 27)
ISODate("2014-04-27T07:00:00Z")

07:00:00Z に注意してください。これらの 7 時間は、私の PDT タイムゾーン (GMT-0700) に基づいています。ISODateしたがって、MongoDB シェルで便利な関数を使用する必要があります。

> ISODate('2014-03-27')
ISODate("2014-03-27T00:00:00Z")
> ISODate('1850-01-01')
ISODate("1850-01-01T00:00:00Z")

適切なタイムゾーンを取得できるようにします。

また、カウントのみを見ているのでfind、MongoDB シェルの 2 番目の引数を省略して、簡単にすることができます。または、を使用{ _id: true }してドロップcount()し、混乱を減らします。

tirdadcと私が指摘した問題を修正し、両方のケースで同じ結果が得られるかどうかを確認してください。そうでない場合は、異なる結果が得られるまで両方のクエリを少しずつ作成し始めて、問題がどこにあるのかがわかります。最初から並べ替えオプションを含め、カウントだけでなく、返されたドキュメント ID を比較することを忘れないでください。

于 2014-03-27T02:33:02.837 に答える