0

いくつかのプロジェクトで、ある時点でMongoDBに切り替えることを検討しています。そのためには、それをテストして、何ができるのか、何ができないのかを知る必要があります。

MongoDBがどのように機能するかについていくつかの本を読んだ後、私は実際にどのように機能するかについて少し混乱していると言わなければなりませんselect

私がというコレクションを持っているとしましょうusers

{
    user_name: string,
    ....,
    ....,
    messages_can_be_seen_by_others: boolean
}

また、私はのコレクションを持っていますtopics

{
    topic_title: string,
    .....,
    .....,
    topic_messages:
        [
            {
                 user_name: string,
                 text: string,
                 date: DateTime
            },
            {
                 user_name: string,
                 text: string,
                 date: DateTime
            }
        ]
    .....
}

usersコレクションに応じて、1つのトピックとそのすべてのメッセージを選択するにはどうすればよいですか?つまり、としてマークされPerson1ていない人によって書かれたメッセージは、データベースによって返されるべきではありません。messages_can_be_seen_by_otherstrue

それで、map / reduceを使用するphpか、すべての結果が得られたらフィルターをかける必要がありますか、それとも私が気付いていない他のことはありますか?map / reduceを使用する必要がある場合、それはどれほど難しいでしょうか?

また、別の質問があります。topics最初のdateメッセージからすべてのフィールドを選択するにはどうすればよいですか?(のようなもの$elemMatch.messages.0.date

PS:追加の質問:トピックに含まれるメッセージの数を返すことはできますか?(PHPを使用して実際にカウントすることはありません。MongoDBselectステートメントを計画するだけです)

よろしく

4

1 に答える 1

1

すべての質問は、MongoDBの2.2バージョン(本日リリースされました!)に付属する新しいAggregationフレームワークで多かれ少なかれ解決できます。

ただし、注意点が1つあります。集約は、単一のコレクションでのみ機能します。最初の質問で、ユーザーコレクションの情報(特にmessages_can_be_seen_by_othersフラグ)とトピックコレクションの情報(メッセージなど)を組み合わせる場合は、Map / Reduceを使用するか、事前に追加のクエリを実行する必要があります。そのユーザーを次のクエリに含めるかどうかを確認するか、名前だけでなく、トピックを含むユーザードキュメント全体を保存します。これはRDBMSでは実行できないことですが、MongoDBのようなドキュメントベースのデータベースの場合、これは非常に一般的な方法です。

それを除けば、すべての問題は集約によって解決できます。例えば

  1. トピックを選択すると、特定のユーザーからのすべてのメッセージを次の構文で実行できます。

    db.topics.aggregate(
        {$match: {'topic_title':'Some Topic Title'}}, 
        {$unwind: '$topic_messages'}, 
        {$match: {'topic_messages.user_name': 'Some User Name'}}, 
        {$group: {'_id':'$topic_title', 'messages': {$addToSet: '$topic_messages'}}}
    )
    

    このクエリは、最初にタイトルに一致するトピックのみをフィルタリングし、次にメッセージを巻き戻し(グループの反対)、特定のユーザーをフィルタリングし、最後にタイトルに従ってメッセージをグループ化します。

  2. すべてのトピックタイトルとそれらの最初の(最も早い)メッセージの日付を検索します。

    db.topics.aggregate(
        {'$unwind': '$topic_messages'}, 
        {'$sort': {'topic_messages.date' : 1}}, 
        {'$group': {'_id': '$topic_title', 
                    'first_date': {'$first': '$topic_messages.date' }
                   }
        }
    )
    
  3. 1つのトピックのすべてのメッセージをカウントします(phpではなくMongoDBを使用)。

    db.topics.aggregate(
        {'$match': {'topic_title': 'Some Topic Title'}}, 
        {'$unwind': '$topic_messages'}, 
        {'$group': {'_id':'$topic_title', 'count': {$sum: 1}}}
    )
    

ご覧のとおり、Aggregationフレームワークは非常に強力であり、必要なすべての情報が1つのコレクションに格納されている限り、シャーディングされたコレクションでも機能します。

于 2012-08-29T15:43:49.140 に答える