sql >> データベース >  >> NoSQL >> MongoDB

GridFSから孤立したファイルを削除する

    まず、時間をかけてGridFS について考えてみましょう。 実際に は。そして、最初に、参照されているマニュアルページから読んでみましょう:

    ですから、それが邪魔にならないので、それがあなたのユースケースになるかもしれません。ただし、ここで学ぶべき教訓は、GridFS ということです。 自動的にではありません ファイルを保存するための「頼りになる」方法。

    あなたのケース(および他のケース)でここで起こったことは、「ドライバーレベル」の仕様によるものです。 これはそうです(そしてMongoDB自体はいいえ ここで魔法)、あなたの「ファイル」は2つのコレクションに「分割」されています。 1つはコンテンツへの主な参照用で、もう1つはデータの「チャンク」用です。

    あなたの問題(および他の人)は、「メイン」参照が削除されたので、「チャンク」を何とか残してしまったことです。ですから、多くの場合、孤児を取り除く方法。

    あなたの現在の読書は「ループして比較する」と言っています、そしてMongoDBは結合をしません 、それなら他に答えはありません。しかし、役立つことがいくつかあります。

    したがって、巨大な$ninを実行するのではなく 、これを分割するためにいくつかの異なることを試してみてください。たとえば、逆の順序で作業することを検討してください。

    db.fs.chunks.aggregate([
        { "$group": { "_id": "$files_id" } },
        { "$limit": 5000 }
    ])
    

    つまり、そこで行っていることは、明確なを取得することです。 「files_id」値(fs.filesへの参照) )、すべてのエントリから、5000のエントリから始めます。その後、もちろんループに戻り、fs.filesをチェックします。 一致する_idの場合 。何かが見つからない場合は、削除 「チャンク」の「files_id」に一致するドキュメント。

    しかし、それは5000でしたので、維持 最後 そのセットでidが見つかりました。これは、同じ集計ステートメントを再度実行するためですが、異なる方法です:

    db.fs.chunks.aggregate([
        { "$match": { "files_id": { "$gte": last_id } } },
        { "$group": { "_id": "$files_id" } },
        { "$limit": 5000 }
    ])
    

    したがって、これは機能します ObjectId 値は単調です。 または「増え続ける」。つまり、すべての新しい エントリは常により大きい 最後。次に、これらの値を再度ループして、見つからない場合は同じ削除を実行できます。

    これは「永遠にかかる」のでしょうか。ええとはい 。あなたはかもしれない db.eval()を使用します このためですが、読む ドキュメント。ただし、全体として、これは2つを使用するために支払う価格です。 コレクション。

    スタート地点に戻る。 GridFS 仕様は設計されています 具体的にしたいので、このように 16MBの制限を回避します。しかし、それがそうでない 制限がある場合は、理由について質問してください。 GridFS を使用しています そもそも。

    MongoDBには問題ありません 特定のBSONドキュメントの任意の要素内に「バイナリ」データを格納します。したがって、必要ありません GridFS を使用するには ファイルを保存するだけです。そして、そうしていれば、すべて 更新のうち、1つにのみ作用するため、完全に「アトミック」になります。 1つのドキュメント 一度にコレクション。

    GridFS 以降 意図的に ドキュメントをコレクション間で分割し、それを使用する場合は、苦痛を伴います。したがって、必要の場合に使用してください それですが、しない場合 、次にBinDataを保存するだけです 通常のフィールドとして、これらの問題はなくなります。

    ただし、少なくとも、すべてをメモリにロードするよりも優れたアプローチがあります。



    1. URLからd3.js配列を取得します

    2. MongoDBで重複レコードを検索する

    3. MongoDB $ atanh

    4. ローカルSQLiteとリモートMongoDB