2017-01-02 5 views
0

祖先の配列を持つモデルツリー構造を使用しています。MongoDB:祖先の配列を持つモデルツリー構造を使って文書が欠落していないか確認してください。

{ 
    "_id" : "GbxvxMdQ9rv8p6b8M", 
    "type" : "article", 
    "ancestors" : [ ] 
} 
{ 
    "_id" : "mtmTBW8nA4YoCevf4", 
    "parent" : "GbxvxMdQ9rv8p6b8M", 
    "ancestors" : [ 
     "GbxvxMdQ9rv8p6b8M" 
    ] 
} 
{ 
    "_id" : "J5Dg4fB5Kmdbi8mwj", 
    "parent" : "mtmTBW8nA4YoCevf4", 
    "ancestors" : [ 
     "GbxvxMdQ9rv8p6b8M", 
     "mtmTBW8nA4YoCevf4" 
    ] 
} 
{ 
    "_id" : "tYmH8fQeTLpe4wxi7", 
    "refType" : "reference", 
    "parent" : "J5Dg4fB5Kmdbi8mwj", 
    "ancestors" : [ 
     "GbxvxMdQ9rv8p6b8M", 
     "mtmTBW8nA4YoCevf4", 
     "J5Dg4fB5Kmdbi8mwj" 
    ] 
} 

私の試みは、各祖先IDが存在するかどうかを確認することです。これが失敗すると、この文書が欠落し、データ構造が壊れています。

let ancestors; 

Collection.find().forEach(r => { 
    if (r.ancestors) { 
     r.ancestors.forEach(a => { 
      if (!Collection.findOne(a)) 
       missing.push(r._id); 
     }); 
    } 
}); 

しかし、このようにすると、たくさんのdbコールが必要になります。これを最適化することは可能ですか? おそらく、すべての一意の祖先IDを持つ配列を取得し、これらのドキュメントが1つのdbコール内に存在するかどうかを確認できますか?

+0

おそらくMongoDB 3.4 – styvane

答えて

0

最初にあなたのコレクションからすべての別個のancesstorsを取り出してください。

var allAncesstorIds = db.<collectionName>.distinct("ancestors"); 

次に、コレクション内にancesstor IDがないかどうかを確認します。

var cursor = db.<collectionName>.find({_id : {$nin : allAncesstorIds}}, {_id : 1}) 

コレクション内のすべての不足しているドキュメントをカーソルに挿入して挿入します。

cursor.forEach(function (missingDocId) { 
    db.missing.insert(missingDocId); 
}); 
+0

$ ninは私には存在しない文書を与えないので、これはうまくいかないでしょう。私はallAncesstorIdsのidが全く存在していないか確認する必要があります。これは、allAncesstorIdsの各要素に対して 'findOne()'を実行すると機能しますが、多くのクエリにつながります... – user3142695

+0

これは、1つ以上のドキュメントのancesstorフィールドに存在するIDですが、 IDは存在しません。これはあなたが望むものではありませんか?あなたは例を挙げることができますか? – ares

0

このようなことを試すことができます。 $祖先を巻き戻してコレクションの祖先と$ルックアップに収集し、見つからないもののみを投影するためにマッチを続けます。最も効率的な方法ではありませんが、すべての処理はサーバー上で行われます。それが懸念される場合は、必ずクエリのパフォーマンスをテストしてください。

db.ancestors.aggregate({ 
    $unwind: "$ancestors" 
}, { 
    $group: { 
     _id: null, 
     uniqueAns: { 
      $addToSet: "$ancestors" 
     } 
    } 
}, { 
    $unwind: "$uniqueAns" 
}, { 
    $lookup: { 
     from: "ancestors", 
     localField: "uniqueAns", 
     foreignField: "_id", 
     as: "matching" 
    } 
}, { 
    $match: { 
     'matching': { 
      $size: 0 
     } 
    } 
}); 
関連する問題