具有非重复字段值的MongoDB集合

时间:2014-07-23 21:22:42

标签: python mongodb mongodb-query aggregation-framework pymongo

所以我对MongoDB很新。这是一个虚构的数据库,格式如下。

{
    "_id": "message_id", 
    "headers": {
        "from": <from_email>,
        "to": <to_email>, 
        "timestamp": <timestamp>
    },   
    "message": {
        "message": <the message contents>, 
        "signature": <signature contents>
    }
} 

假设收到的所有电子邮件都插入其中,有时会发送电子邮件。如何在没有任何双重发送的情况下从作者返回电子邮件集合。

我认为这可能会这样做,但它似乎没有按预期工作:

db.mycoll.find({"headers.from": <authorname>}).distinct("message.message")

编辑: 请原谅,似乎我一直在制作某种拼写错误,上面的查询有效,但它只返回messages.messages而没有Headers,我如何保持标题完好无损?

5 个答案:

答案 0 :(得分:1)

很难从您的问题中确定哪个部分是“重复”,因此应该是唯一的。虽然诸如消息“_id”和“timestamp”之类的东西不会重复,但是这只是真正留下了消息内容,并且该消息可能会“脱离”同一个人。< / p>

文档重塑通常最好由aggregation framework处理:

db.collection.aggregate([
    { "$group": {
        "_id": { "message": "$message.message", "from": "$headers.from" },
        "message_id": { "$first": "$_id" },
        "headers": { "$first": "$headers" },
        "message": { "$first": "$message" }
    }},
    { "$project": {
        "_id": "$message_id",
        "headers": 1,
        "message": 1
    }}
])

$group将使用$first操作过滤掉任何匹配的邮件内容,只选择文档分组边界上匹配字段的“第一个”找到的项目。

此处假设现有订单是“timestamp”,但如果没有,那么您可能希望将$sort作为第一个管道阶段应用于其他管道阶段:

{ "$sort": { "headers.timestamp": 1 } }

最终$project实际上只是恢复了原始文档表单,并删除了之前提供的“分组键”。比复制信息和/或放置不合适的东西更漂亮。

答案 1 :(得分:0)

您可以使用distinct()从特定作者返回一系列不同的消息,如下所示:

db.collection.distinct('message.message', {"headers.from": <authorname>})

答案 2 :(得分:0)

您目前尚未实施的内容(至少据我所知)。一个解决方法是this

答案 3 :(得分:0)

db.mycoll.aggregate([
{
  $match:{"headers.from": <authorname>}
},{
   $group:{
   _id:"$headers.from",
   "message":{$addToSet:"$message.message"}
}
}

])

答案 4 :(得分:0)

以Neil Lunn的答案为基础: 我认为可以做到

db.collection.aggregate([{"$match": {"headers.from": <from email>} } ,
{"$group": { "_id": "$message.message"}, 
"headers": {"$first": "$headers"}, 
"signature": {"$first": "$message.signature"},
 "message_id": "$_id" }}, 
{"$project" : { "_id": "$message_id", 
"headers": "$headers", 
"message": { "message": "$_id", "signature": "$signature" } } }]) 

由于_id必须是唯一的,因此重复的消息不会生成列表,然后$project会将其重组为具有正确键名的原始对象结构。

我想我在这方面只有一个问题 - 有没有办法强制唯一性而不会聚合到_id中,或者这通常被认为是在MongoDB中执行此操作的正确方法吗?