MongoDB aggregate Query with select fields - mongodb

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
}

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.

Related

is it possible to use "or" in query part of update method in mongodb

Can I use or in query part of update method in mongodb.
If yes then what am I doing wrong because the upsert is not working.
I get two different type of result when I use and don't use or.
when I use or only the data.message is inserted and when I use don't use or all the data is inserted if it does not exist and it exist data.messages gets added to messages.
db.chatdata.update(
{$or:[
{'receiverId':data.receiver_id,
'senderId':data.sender_id
},
{'receiverId':data.sender_id,
'senderId':data.receiver_id
}]
},
{$addToSet:{'messages':data.message}},
{upsert:true},
callback)
expected output
{
"_id" : ObjectId("5986f850e1bf9b531154e52d"),
"receiverId" : "5985864dd06db71fa4c2ce69",
"senderId" : "59857707f6de9106fc936003",
"messages" : [
{
"_id" : ObjectId("5986f8509bda810a140e975d"),
"message" : "hello apple",
"time" : "1502017616523"
},
{
"_id" : ObjectId("5986f8a19bda810a140e9768"),
"message" : "hello apple",
"time" : "1502017697484"
}
],
"__v" : 0
}
actual output
{
"_id" : ObjectId("59872ec4e1bf9b531154eedd"),
"messages" : [
{
"_id" : ObjectId("59872ec4827f9737949589f3"),
"message" : "helo",
"time" : "1502031556694"
}
],
"__v" : 0
}

Search MongoDB and for the same field I want to exclude some results

I search for all the docs with status "request" but I want to exclude all the documents with the status "notInterested".
Here is the code:
getRelationships(){
return Relationships.find({
'whoId': Meteor.userId(),
'status' : 'request',
'status' : {$ne : 'notInterested'}
});
}
Not working now, but I have no errors.
In my below sample collection, there are three documents for "whoId" equals 123. Out of which two documents have status as "request" and one has "notInterested". The query has condition to include specific status (i.e. request) and exclude status (i.e. notInterested) as well.
The $and operator can be used to achieve this. If I understand your question correctly, this solution should resolve your problem.
My Relationships collection data:-
/* 1 */
{
"_id" : ObjectId("579e0d1d681b1cf15a897776"),
"whoId" : "123",
"status" : "request"
}
/* 2 */
{
"_id" : ObjectId("579e0d2f681b1cf15a897777"),
"whoId" : "2321111",
"status" : "notInterested"
}
/* 3 */
{
"_id" : ObjectId("579e0d5d681b1cf15a897778"),
"whoId" : "123",
"status" : "request"
}
/* 4 */
{
"_id" : ObjectId("579e0d65681b1cf15a897779"),
"whoId" : "123",
"status" : "notInterested"
}
Query :-
db.Relationships.find({whoId : '123', $and : [{status : 'request'}, {status : {$ne : 'notInterested'}}]})
Result:-
Please note that the status 'notInterested' has not been selected.
/* 1 */
{
"_id" : ObjectId("579e0d1d681b1cf15a897776"),
"whoId" : "123",
"status" : "request"
}
/* 2 */
{
"_id" : ObjectId("579e0d5d681b1cf15a897778"),
"whoId" : "123",
"status" : "request"
}

query Mongo db for list of object inside object collection

my collection is like this:
{
"_id" : ObjectId("56b888ae31c1d1d3bf79f8c6"),
"_class" : "fore.server.domain.post.UserPost",
"image" : { "_id" : null, "statusText" : "This food i cooked" },
"healthRates" : [
{
"_id" : null,
"rateValue" : "VerryPoor",
"uid" : { "_id" : "HS-56541" }
}
]
}
and i want to query for all the collection which has the user id as follows:
{"uid" : { "_id" : "HS-56541" }}
but my query get nothing !! i tried the following !
db.userPost.find({healthRates:{$elemMatch: "uid" : { "_id" : "HS-56541" } } )
and i tried
db.userPost.find({"healthRates.uid.id" : "HS-56541" } )
without a result! any suggestion please?
You were on correct track by using $elemMatch to query the embedded array inside of your document. The following query will work:
db.userPost.find({healthRates:{$elemMatch:{uid._id:"HS-56541"}}})

mongodb queries find total number of cities in the database

Hi everyone I have a huge data that contains some information like this below:
{ "_id" : "01011", "city" : "CHESTER", "loc" : [ -72.988761, 42.279421 ], "pop" : 1688, "state" : "MA" }
{ "_id" : "01012", "city" : "CHESTERFIELD", "loc" : [ -72.833309, 42.38167 ], "pop" : 177, "state" : "MA" }
{ "_id" : "01013", "city" : "CHICOPEE", "loc" : [ -72.607962, 42.162046 ], "pop" : 23396, "state" : "MA" }
{ "_id" : "01020", "city" : "CHICOPEE", "loc" : [ -72.576142, 42.176443 ], "pop" : 31495, "state" : "MA" }
I want to be able to find the number of the cities in this database using Mongodb command. But also the database may have more than one recored that has the same city. As the example above.
I tried:
>db.zipcodes.distinct("city").count();
2015-04-25T15:57:45.446-0400 E QUERY warning: log line attempted (159k) over max size (10k), printing beginning and end ... TypeError: Object AGAWAM,BELCHERTOWN ***data*** has no method 'count'
but I didn't work with me.Also I did something like this:
>db.zipcodes.find({city:.*}).count();
2015-04-25T16:00:01.043-0400 E QUERY SyntaxError: Unexpected token .
But it didn't work also and even if does work it will count the redundant data (city). Any idea?
Instead of doing
db.zipcodes.distinct("city").count();
do this:
db.zipcodes.distinct("city").length;
and there is aggregate function, which may help you.
I have also found 1 example on aggregate (related to your query).
If you want to add condition, then you could refer $gte / $gte (aggregation) and/or $lte / $lte (aggregation)
See, if that helps.
You can also use the aggregation framework for this. The aggregation pipeline has two $group operator stages; the first groups the documents by city and the last calculates the total distinct documents from the previous stream:
db.collection.aggregate([
{
"$group": {
"_id": "$city"
}
},
{
"$group": {
"_id": 0,
"count": { "$sum": 1 }
}
}
]);
Output:
/* 1 */
{
"result" : [
{
"_id" : 0,
"count" : 3
}
],
"ok" : 1
}

MongoDB Aggregation Framework: Getting $unwind error when using $group

I have a document structure as follows:
{
"_id" : NumberLong("80000000012"),
[...]
"categories" : [{
"parent" : "MANUFACTURER",
"category" : "Chevrolet"
}, {
"parent" : "MISCELLANEOUS",
"category" : "Miscellaneous"
}],
[...]
}
I am trying to get a distinct list of all 'category' fields for each 'parent' field. I was trying to utilize the aggregation framework to do this with the following query:
db.posts_temp.aggregate(
{$unwind : '$categories'},
{$match : {'categories.parent' : 'MISCELLANEOUS'}},
{$project : {
'_id' : 0,
parent : '$categories.parent',
category : '$categories.category'
}
},
{
$group : {
_id : '$parent',
category : {$addToSet : '$category'}
}
}
);
Running this query returns the following error:
{
"errmsg" : "exception: $unwind: value at end of field path must be an array",
"code" : 15978,
"ok" : 0
}
This seems to be tied to the group portion of the query, because, when I remove it, the query runs correctly, but, obviously, the data is not where I want it to be.
I just tried executing the above aggregation query on my mongo instance. Here are my 3 documents each with a key of categories that has an array of two nested documents.
Here is my data:
{
"_id" : ObjectId("512d5252b748191fefbd4698"),
"categories" : [
{
"parent" : "MANUFACTURER",
"category" : "Chevrolet"
},
{
"parent" : "MISCELLANEOUS",
"category" : "Miscellaneous"
}
]
}
{
"_id" : ObjectId("512d535cb748191fefbd4699"),
"categories" : [
{
"parent" : "MANUFACTURER",
"category" : "Chevrolet"
},
{
"parent" : "MISCELLANEOUS",
"category" : "Pickup"
}
]
}
{
"_id" : ObjectId("512d536eb748191fefbd469a"),
"categories" : [
{
"parent" : "MANUFACTURER",
"category" : "Toyota"
},
{
"parent" : "MISCELLANEOUS",
"category" : "Miscellaneous"
}
]
}
Here is the aggregation query of yours that I ran:
db.posts_temp.aggregate( {$unwind:'$categories'} , {$match: {'categories.parent':'MISCELLANEOUS'}}, {$project:{'_id':0, parent: '$categories.parent', category:'$categories.category'}}, {$group:{_id:'$parent', category:{$addToSet:'$category'}}})
Here is the result:
{
"result" : [
{
"_id" : "MISCELLANEOUS",
"category" : [
"Pickup",
"Miscellaneous"
]
}
],
"ok" : 1
}
Let me know if there some discrepancies between my data and yours.
CSharpie