【问题标题】:How to use not equal operator in mongoose/mongodb?如何在 mongoose/mongodb 中使用不等于运算符?
【发布时间】:2016-09-25 19:19:44
【问题描述】:

这是文档的结构。

{
    "_id" : ObjectId("5548f1cc0dcd6bd925a71ae2"), //document id
    "messages" : [
        {
            "subject" : "NEW ++ SUBJECT",
            "from" : ObjectId("5534b2992a104ed914435c31"),
            "_id" : ObjectId("5548f1cc0dcd6bd925a71ae3"),
            "created" : ISODate("2015-05-05T16:37:32.832Z"),
            "read" : false,
            "message" : "FIRST MESSAGE",
            "participants" : [
                ObjectId("5534b2992a104ed914435c31"),
                ObjectId("5530af38576214dd3553331c")
            ]
        },
        {
            "subject" : "dfgsd",
            "from" : ObjectId("5534b2992a104ed914435c98"),//logged In USer
            "_id" : ObjectId("5548f1df0dcd6bd925a71ae4"),
            "created" : ISODate("2015-05-05T16:37:51.455Z"),
            "read" : false,
            "message" : "rdfgdgfd",
            "participants" : [
                ObjectId("5534b2992a104ed914435c98"),//logged In USer
                ObjectId("5530af38576214dd3553331c")
            ]
        }
    "participants" : [
        ObjectId("5534b2992a104ed914435c98"),//logged In USer
        ObjectId("5534b2992a104ed914435c31"),
        ObjectId("5530af38576214dd3553331c")
    ],
    "__v" : 3

}

我想获取消息数组的消息对象,其“读取”值为“假”且“来自”不等于登录用户(此处登录用户为 5534b2992a104ed914435c98)。并且文档的“参与者”数组必须包含登录的用户 ID(5534b2992a104ed914435c98)。这是我尝试的查询。

db.conversations.find({participants:ObjectId('5534b2992a104ed914435c98'),'messag‌​es.read':false,'messages.from':{$ne:ObjectId('5534b2992a104ed914435c98')}}).prett‌​y().

基本上我正在尝试获取未读消息的计数。 我对 mongodb/mongoose 很陌生。如果您发现问题有问题,请纠正我。

【问题讨论】:

  • 所以在你上面的例子中什么都不会返回?我也对您如何存储数据感到有些困惑(该文档代表什么?)似乎最后的participants 也应该有31c
  • 请给我一个给出所需结果的查询。???你能告诉我们你的尝试吗,好像你一直在发布类似的问题,但没有对所提供的答案提供反馈。
  • @ExplosionPills :是的,我现在已经修改了。
  • @chridam:很抱歉反馈迟了。这是我尝试过的代码。 db.conversations.find({participants:ObjectId('5534b2992a104ed914435c98'),'messages.read':false,'messages.from':{$ne:ObjectId('5534b2992a104ed914435c98')}}).pretty() 请纠正我如果我错了
  • @chridam 感谢您的回复。我现在已经编辑了

标签: node.js mongodb mongoose


【解决方案1】:

如果您尝试根据“已读”值为“假”和“来自”的消息数组不等于登录用户(此处登录用户为 @987654332 @) 并且文档的 'participants' 数组必须包含登录用户 ID 5534b2992a104ed914435c98,那么 aggregation framework 方法应该可以帮助您获得所需的结果。

聚合管道的第一个管道阶段应该是满足上述条件的$match 查询。这会过滤需要在管道流中进一步处理的文档。

对于不使用 $unwind 运算符在处理之前先展平消息数组的解决方案,请考虑以下 $filter$size 运算符:

var pipeline = [
    {
        "$match": {
            "participants": ObjectId("5534b2992a104ed914435c98"),
            "messages.read" : false,
            "messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
        }
    },    
    {
        "$project": {
            "_id": 0,
            "unread_messages": {
                "$size": {
                    "$filter": {
                        "input": "$messages",
                        "as": "msg",
                        "cond": {
                            "$and": [
                                { "$not": [ "$$msg.read" ] },
                                { "$ne": ["$$msg.from", ObjectId('5534b2992a104ed914435c98')]}
                            ]
                        }
                    }
                }
            }
        }

    }
]

db.conversations.aggregate(pipeline)

如果您使用的驱动程序不支持上述运算符,请考虑将$match 之后的下一个管道阶段作为$unwind 操作,该操作用于解构messages 数组,以便您可以输出一个每个元素的文档。

需要对解构的消息使用$match 运算符进行进一步过滤,以仅允许那些符合早期标准的消息在管道中进一步处理。

这部分操作对于下一个管道阶段是必需的,$group 运算符按指定的标识符表达式对传入的文档进行分组,并将 $sum 累加器表达式应用于每个组,以便您可以获得总数组中的文件。

最后阶段使用$project 运算符通过抑制_id 字段来重塑流中的最终结果文档,并添加一个新字段unread_messages,该字段描述read 字段值为false 的消息总数.

最终的聚合管道如下所示:

var pipeline = [
    {
        "$match": {
            "participants": ObjectId("5534b2992a104ed914435c98"),
            "messages.read" : false,
            "messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
        }
    },
    {
        "$unwind": "$messages"
    },
    {
        "$match": {
            "participants": ObjectId("5534b2992a104ed914435c98"),
            "messages.read" : false,
            "messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
        }
    },
    {
        "$group": {
            "_id": null,
            "count": {
                "$sum": 1
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "unread_messages": "$count"
        }

    }
]

您可以在 Mongoose 聚合中使用它,如下所示:

Conversations.aggregate(pipeline, function (err, res) {
    if (err) return handleError(err);
    console.log(res); // [ { unread_messages: 34 } ] <-- this is a made up value :-)
});)

或者使用聚合管道构建器:

Conversations.aggregate()
    .match({
            "participants": ObjectId("5534b2992a104ed914435c98"),
            "messages.read" : false,
            "messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
    })
    .unwind("messages")
    .match({
            "participants": ObjectId("5534b2992a104ed914435c98"),
            "messages.read" : false,
            "messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
    })
    .group({ "_id": null, "unread_messages": { "$sum": 1 } })
    .select("-id unread_messages")
    .exec(function (err, res) {
        if (err) return handleError(err);
        console.log(res); // [ { unread_messages: 34 } ] <-- this is a made up value :-)
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-10
    • 2019-03-19
    • 2013-12-09
    • 2015-06-21
    • 2022-12-12
    • 2016-06-13
    • 2012-05-21
    相关资源
    最近更新 更多