2

I want to make chat system, and also need get last message of user which aggigation. I also provide query with this but it only return userId of user. so please help me, thanks

Database:

/* 1 */
{
    "_id" : ObjectId("56937df0418a6afab248616d"),
    "to" : ObjectId("56728051d4b426be03de18f2"),
    "from" : ObjectId("568e402eaecfa53282f60d17"),
    "msg" : "Hello!",
    "cd" : ISODate("2016-01-11T10:03:28.139Z"),
    "type" : "other",
    "ir" : 0
}

/* 2 */
{
    "_id" : ObjectId("56937e01418a6afab248616e"),
    "to" : ObjectId("568e402eaecfa53282f60d17"),
    "from" : ObjectId("56728051d4b426be03de18f2"),
    "msg" : "Hi!",
    "cd" : ISODate("2016-01-11T10:03:45.588Z"),
    "type" : "other",
    "ir" : 0
}

/* 3 */
{
    "_id" : ObjectId("56937e45418a6afab248616f"),
    "to" : ObjectId("56728051d4b426be03de18f2"),
    "from" : ObjectId("568e402eaecfa53282f60d17"),
    "msg" : "Shu che ela!",
    "cd" : ISODate("2016-01-11T10:04:53.280Z"),
    "type" : "other",
    "ir" : 0
}

Query:

db.getCollection('chat_message').aggregate( [
        { 
            $match: {
                ir: 0, 
                $or : [
                    {"to" : ObjectId("56728051d4b426be03de18f2")}
                ]  
            } 
        },

        { $group: { _id: "$from" } },

    ])

I Run this query but not get result which i want

Require Out came:

/* 1 */
{
    "result" : [ 
        {
            "_id" : ObjectId("568e402eaecfa53282f60d17"),
            "msg" : "Shu che ela!"
        }
    ],
    "ok" : 1.0000000000000000
}

1 Answer 1

3

You are right track but you missing some things about $mongo object Id

In MongoDB, documents stored in a collection require a unique _id field that acts as a primary key.

so when you run your aggregation query $group creates _id for from key but in your document structure looks like from having two documents with same ObjectId since the result return first matching criteria. This return only "msg" : "Hello!", or "msg" : "Shu che ela!" which documents inserted first return first.

so should changed your aggreation like this {"$group":{"_id":"$_id","msg":{"$first":"$msg"}}} you will get both documents.

Sign up to request clarification or add additional context in comments.

1 Comment

db.getCollection('chat_message').aggregate( [ { $match: { ir: 0, $or : [ {"to" : ObjectId("56728051d4b426be03de18f2")} ] } }, {"$group":{"_id":"$from","msg":{"$last":"$msg"}}} ]) I put this query and i got last message as par i want. thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.