0

我正在考虑在某些时候为我的一些项目切换到 MongoDB。为此,我需要对其进行测试并知道我能做什么和不能做什么。

select在阅读了一些关于 MongoDB 如何工作的书籍之后,我必须说我对's 的实际工作方式有点困惑。

假设我有一个名为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集合选择一个主题及其所有消息?Person1我的意思是,由没有messages_can_be_seen_by_others标记为的人写的消息不true应该被数据库返回。

那么,我应该使用 map/reduce,在php获得所有结果后进行过滤,还是还有其他我不知道的事情?如果我应该使用 map/reduce 会有多困难?

另外,还有一个问题。如何从第一条消息topics中选择所有字段?date(有点像$elemMatch.messages.0.date

PS:额外的问题:我可以返回一个主题的消息数吗?(实际上没有使用 PHP 计算它们。只需计划 MongoDB 选择语句)

问候

4

1 回答 1

1

您的所有问题或多或少都可以通过2.2 版本的 MongoDB(今天发布!)附带的新聚合框架来解决。

但是有一个警告:聚合仅适用于单个集合。在您的第一个问题中,如果您想将用户集合(特别是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. 计算一个主题的所有消息(使用 MongoDB,而不是 php):

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

所以你看,聚合框架非常强大,甚至可以在分片集合上工作,只要你需要的所有信息都存储在一个集合中。

于 2012-08-29T15:43:49.140 回答