1

ドキュメントがすべてこの形式であるコレクションがあります。

{"user_id": ObjectId, "book_id": ObjectId}

これは、ユーザーと本の関係を表します。これも1対多です。つまり、ユーザーは複数の本を持つことができます。

今、私は3つを手に入れbook_idました、例えば:

["507f191e810c19729de860ea", "507f191e810c19729de345ez", "507f191e810c19729de860efr"]

この3冊の本を持っているユーザーに質問したいのですが、このコレクションのドキュメントではなく、新しく作成された配列であるuser_idため、複雑に見え、クエリの作成方法がわかりません。助けてください。自分。

ノート:

次のような構造を使用しなかった理由:

{"user_id": ObjectId, "book_ids": [ObjectId, ...]}

私のシステムでは、本が頻繁に増えて量に制限がない、つまりユーザーが何千冊もの本を読む可能性があるため、従来の方法で保管する方が良いと思います。

この質問はMongoDBによって制限されていません。リレーショナル・データベースの考えで答えることができます。

4

1 に答える 1

2

レギュラーを使用するfindと、コレクションを正規化(フラット化)したため、すべてのbook_idを所有するすべてのuser_idフィールドを取得することはできません。

集約フレームワークを使用する場合は、次のように実行できます。

db.collection.aggregate([
    {
        $match: {
            book_id: {
                $in: ["507f191e810c19729de860ea",
                      "507f191e810c19729de345ez",
                      "507f191e810c19729de860efr" ]
            }
        }
    },
    {
        $group: {
            _id: "$user_id",
            count: { $sum: 1 }
        }
    },
    {
        $match: {
            count: 3
        }
    },
    {
        $group: {
            _id: null,
            users: { $addToSet: "$_id" }
        }
    }
]);

これは、3つのbook_id値の1つに一致するドキュメントのみをパイプラインでフィルタリングし、user_idでグループ化して、そのユーザーが取得した一致の数をカウントします。3つ取得すると、次のパイプライン操作に渡され、user_idの配列にグループ化されます。このソリューションは、各'user_id、book_id'レコードが元のコレクションに1回だけ表示できることを前提としています。

于 2013-03-19T06:35:39.290 に答える