2016-12-09 6 views
1

私はMongo初心者ですので、これは簡単な質問かもしれません。私と一緒にご負担願います:)すべてのサブ文書が条件と一致するMongoDB文書を入手してください

Mongo文書は、論理的に有効アーカイブ文書にグループ化することができます。 revisions.validToの日付フィールドがnullまたは今日より大きい場合、ドキュメントは有効です。それ以外の場合、ドキュメントはアーカイブにあります。

だからコレクションの構造はおおよそ次のとおりです。

[ 
    { 
     _id: 'valid-1', 
     info: 'This is valid document because it has a revision with null validTo value', 
     revisions: [ 
      { 
       validTo: ISODate("2014-01-01T00:00:00.000Z") 
      }, 
      { 
       validTo: null 
      } 
     ] 
    }, 
    { 
     _id: 'valid-2', 
     info: 'This is valid document because it has a revision with validTo value > today', 
     revisions: [ 
      { 
       validTo: ISODate("2014-01-01T00:00:00.000Z") 
      }, 
      { 
       validTo: ISODate("2050-01-01T00:00:00.000Z") 
      } 
     ] 
    }, 
    { 
     _id: 'archive-1', 
     info: 'This document is in archive as all revisions have validTo < today', 
     revisions: [ 
      { 
       validTo: ISODate("2014-01-01T00:00:00.000Z") 
      } 
     ] 
    } 
] 

私は簡単に[valid-1, valid-2]返し

db.getCollection('collection').find({ 
    $or: [ 
    { 'revisions.validTo': { $gte: new Date() } }, 
    { 'revisions.validTo': null } 
    ] 
}) 

と妥当な文書を照会することができますが、私はアーカイブを照会する方法を見つけることができません結果を得るための文書[archive-1]。それが今日validTo <を持つ任意のリビジョンを持っている場合たとえば、

db.getCollection('collection').find({ 
    'revisions.validTo': { $lte: new Date() } 
}) 

は、ドキュメントを返します。その代わりに、revisions.validToが今日は<の場合にのみ、私は文書を取得したいと考えています。

コレクションがこれらの2つのグループに正確に分かれているので、有効なグループを照会し、コレクション全体と有効なドキュメントセットを差し引いてアーカイブグループを取得することもできます。これはおそらくMongo集約フレームワークで行うことができますが、私はまだそれを行う方法を見つけることができませんでした。

したがって、アーカイブ文書のクエリを構築する際の助けは大歓迎です!

(つまり、何とか助けることができれば、私はまた、マングースを使用しています..?)

+0

を返すこと。あなたの期待している結果は何ですか? – styvane

+0

私は 'ISODate'を使うためにサンプルコレクションを編集しました。期待される出力についてもう少し説明を加えました。 – ronkot

答えて

1

あなたは以下のように$and$not$ne事業者としてみてくださいすることができ、

db.getCollection('collection').find({ 
    $and: [ 
    { 'revisions.validTo': { $lte: new Date() } }, 
    { 'revisions.validTo': { $not: { $gte: new Date() } } }, 
    { 'revisions.validTo': { $ne: null } } 
    ] 
}) 
+0

うわー、うまくいった!実際、 '$ lte'基準は必要ないと思われます。このトリックは、 'revisions.validTo'が今日よりも大きくないことを述べることでした。私はこの周りに頭を包むのにどれくらいの時間がかかったのか信じられない。ありがとうございました!! – ronkot

0

あなたが最初に必要になります日付をISODatesにして操作を照会できるように文書を再作成する

[ 
    { 
     info: 'This is valid document because it has a revision with null validTo value', 
     revisions: [ 
      { 
       validTo: ISODate("2014-01-01T00:00:00.000Z") 
      }, 
      { 
       validTo: null 
      } 
     ] 
    }, 
    { 
     info: 'This document is in archive as all revisions have validTo < today', 
     revisions: [ 
      { 
       validTo: ISODate("2014-01-01T00:00:00.000Z") 
      } 
     ] 
    } 
] 

これで、クエリ:

db.docs.find({ 'revisions.validTo': { $lte: new Date() }, 'revisions.validTo': { $ne: null } }).pretty() 

あなた `validTo`は、ISO日付もshoud

{ 
     "_id" : ObjectId("584a9a9212767a1fecf0e39f"), 
     "info" : "This document is in archive as all revisions have validTo < today", 
     "revisions" : [ 
       { 
         "validTo" : ISODate("2014-01-01T00:00:00Z") 
       } 
     ] 
} 
+0

お返事ありがとうございます!残念ながら、このアプローチはうまくいかないようです。私が正しく理解していれば、同じオブジェクトキー( 'revisions.validTo')を数回使用すると、最後の基準だけが実際に使用されます。だから、 '$と:[...]'または '$と'を 'revisions 'で暗黙的に使うべきです。validTo:{$ ne:null、$ not:{$ gt:new Date()}} '。 – ronkot

関連する問題