How to project specific elements in an Array field in MongoDB? - node.js

I have this data in MongoDB:
{
"_id" : ObjectId("5c7e459f875ea5548de25722"),
"Autos" : [
{
"_id" : ObjectId("5cad9759e1c3895999adaceb"),
"deleted" : 1,
},
{
"_id" : ObjectId("5cad9a8be1c3895999adacef"),
"deleted" : 0,
},
{
"_id" : ObjectId("5cad9aa4e1c3895999adacf0"),
"deleted" : 0,
}
]
}
{
"_id" : ObjectId("5c7e45e9875ea5548de25724"),
"Shoemaking" : [
{
"_id" : ObjectId("5cad9770e1c3895999adacec"),
"deleted" : 1,
},
{
"_id" : ObjectId("5cad9a5de1c3895999adaced"),
"deleted" : 0,
},
]
I want to basically select * from table where deleted = 0
show where the deleted records are equal to 0.
Here is what I have tried so far:
db.rental.find({"Autos.deleted":{$ne: 1}}).pretty()
db.rental.find({"Autos": {$elemMatch: {deleted: 1 } } } ).pretty()
db.rental.find({"Autos.deleted": 0},{"Autos": {$elemMatch:
{deleted:0}}});
But none of the above work for me. What am I doing wrong?
Desired output:
{
"_id" : ObjectId("5c7e459f875ea5548de25722"),
"Autos" : [
{
"_id" : ObjectId("5cad9a8be1c3895999adacef"),
"deleted" : 0,
},
{
"_id" : ObjectId("5cad9aa4e1c3895999adacf0"),
"deleted" : 0,
}
]
}
{
"_id" : ObjectId("5c7e45e9875ea5548de25724"),
"Shoemaking" : [
{
"_id" : ObjectId("5cad9a5de1c3895999adaced"),
"deleted" : 0,
},
]
}
I want the output to be something like the above, but all the queries I have tried so far either select only one record of Array or select nothing at all.

db.rental.aggregate([
{
$project: {
Autos: {
$filter: {
input: "$Autos",
as: "auto",
cond: { $eq:["$$auto.deleted",0] }
}
}
}
}
])

db.rental.find({ "Autos.deleted": { $eq: 0 } } )

use $elemMatch to match contain inside array. mongodb-$elemMatch
db.rental.find({
Autos: {
$elemMatch: {
deleted: 0
}
}
})

Related

how to check if any of the value in a column is null it shld count value 1 in mongoose?

how to check if any of the value in a column is null it shld count value 1 in mongoose?
i tried
data: {
$max: {
$cond: [{
$or: [{ $eq: ["$mycolumn", null] },
// { $eq: [ "$anotherField","value"] }
]
},
0,
1]
}
},
but this is returning null.how to fix this?Thanks in advance
my collection is
{ _id: 1, item: null ,name:sam,status:open},
{ _id: 2, item: null ,name:arun,status:open},
{ _id: 2, item: 1,name:arun,status:close},
{ _id: 2, item: 1,name:sam,status:close},
also i have to retrieve by grouping status.
Please try this :
db.yourCollectionName.aggregate([{$group: {_id : '$status',
sumOfItem : {$sum : {$cond: [ { $eq: [ "$item", null ] }, 1, '$item' ]}}}}])
(Or)
/** If you've to check if field exists & also field value == null to return 1
or original item value try below - but this might not be needed,
if you don't want to check field exists cause `$ifNull` internally does both checks */
db.yourCollectionName.aggregate([{$group: {_id : '$status', sumOfItem : {$sum : { $ifNull: [ "$item", 1 ] }}}}])
Collection Data :
/* 1 */
{
"_id" : 1.0,
"item" : null,
"name" : "sam",
"status" : "open"
}
/* 2 */
{
"_id" : 2.0,
"item" : null,
"name" : "arun",
"status" : "open"
}
/* 3 */
{
"_id" : 3.0,
"item" : 1.0,
"name" : "arun",
"status" : "close"
}
/* 4 */
{
"_id" : 4.0,
"item" : 1.0,
"name" : "sam",
"status" : "close"
}
/* 5 */
{
"_id" : 5.0,
"item" : 3,
"name" : "sam3",
"status" : "open"
}
Result :
/* 1 */
{
"_id" : "close",
"sumOfItem" : 2.0
}
/* 2 */
{
"_id" : "open",
"sumOfItem" : 5.0
}
Just in case if you don't want sum of item field but just want total open & close statuses(you don't have to check for null) then try this :
db.yourCollectionName.aggregate([{$group: {_id : '$status', total : {$sum : 1}}}])
**Result :**
/* 1 */
{
"_id" : "close",
"total" : 2.0
}
/* 2 */
{
"_id" : "open",
"total" : 3.0
}
By using addFields , We can set 1 value of item if item is null after count the status
db.demo.aggregate(
[{ "$addFields": {
"item":
{
$ifNull: [ '$item', 1 ]
}
},
},
{
$group: {
_id: '$status' ,
count: { '$sum': '$item' },
}
}
]);

query to get all _id in array in mongdb?

I have following collection
{
"_id" : ObjectId("5acdb95d5ea63a27c1facf92"),
"venue" : ObjectId("5acdb95d5ea63a27c1facf8c"),
"author" : ObjectId("5ac8ba3582c2345af70d4658"),
}
{
"_id" : ObjectId("5acdb95d5ea63a27c1facf93"),
"venue" : ObjectId("5acdb95d5ea63a27c1facf8c"),
"author" : ObjectId("5ac8ba3582c2345af70d4658"),
}
{
"_id" : ObjectId("5acdb95d5ea63a27c1facf91"),
"venue" : ObjectId("5acdb95d5ea63a27c1facf8c"),
"author" : ObjectId("5ac8ba3582c2345af70d4658"),
}
how to get all _id in an array having same venue
My output should be like this
{array: ['5acdb95d5ea63a27c1facf91', '5acdb95d5ea63a27c1facf91', '5acdb95d5ea63a27c1facf93']}
Try this query:
db.colelction.aggregate([
{$match:{"venue" : ObjectId("5acdb95d5ea63a27c1facf8c")}},
{$group:{_id:null, array:{$push:"$_id"}}},
{$project:{_id:0}}
])
And the output is:
/* 1 */
{
"array" : [
ObjectId("5acdb95d5ea63a27c1facf92"),
ObjectId("5acdb95d5ea63a27c1facf93"),
ObjectId("5acdb95d5ea63a27c1facf91")
]
}
db.collection.aggregate(
// Pipeline
[
// Stage 1
{
$group: {
_id:{venue:'$venue'},
_ids:{$addToSet:'$_id'}
}
},
// Stage 2
{
$project: {
_ids:1,
_id:0
}
}
]
);

Mongo Node driver how to get all fields of $max aggregate from an array of objects

I have a collection called "products" which has an array of "bids" objects.
I want to find out the Maximum bid for each product, for this I am aggregating Products on $max with $bids.bidamount field. However this is only giving me the largest bid amount. How do I project all the bid fields for the max aggregation.
Here is a sample document
{
"_id" : ObjectId("58109a5138fe12215cfdc064"),
"product_id" : 2,
"item_name" : "Auction Item1",
"item_description" : "Test",
"seller_name" : "ak#gmail.com",
"item_price" : "20",
"item_quantity" : 7,
"sale_type" : "Auction",
"posted_at" : "2016:10:26 04:58:09",
"expires_at" : "2016:10:30 04:58:09",
"bids" : [
{
"bid_id" : 1,
"bidder" : "ak#gmail.com",
"bid_amount" : 300,
"bit_time" : "2016:10:26 22:36:29"
},
{
"bid_id" : 2,
"bidder" : "ak#gmail.com",
"bid_amount" : 100,
"bit_time" : "2016:10:26 22:37:29"
}
],
"orders" : [
{
"buyer" : "ak#gmail.com",
"quantity" : "2"
},
{
"buyer" : "ak#gmail.com",
"quantity" : "3"
}
]
}
Here is my mongo query:
db.products.aggregate([
{
$project: {
bidMax: { $max: "$bids.bid_amount"}
}
}
])
which gives the following result:
{
"_id" : ObjectId("58109a5138fe12215cfdc064"),
"bidMax" : 300
}
db.products.aggregate([{$unwind:"$bids"},{$group:{_id:"$_id", sum:{$sum:"$bids.bid_amount"}}},{$project:{doc:"$$ROOT", _id:1, sum:1}, {$sort:{"sum":-1}},{$limit:1}]),
which return something like { "_id" : ObjectId("5811b667c50fb1ec88227860"), "sum" : 600, doc:{your document....} }
This should do it:
db.products.aggregate([{
$unwind: '$bids'
}, {
$group: {
_id: '$products_id',
maxBid: {
$max: '$bids.bid_amount'
}
}
}])
db.collectionName.aggregate(
[
{
$group:
{
_id: "$product_id",
maxBidAmount: { $max: "$bids.bid_amount" }
}
}
]
)
Hey use this query, you will get the result.

mongoose sort by dates from array

I have a Chat model which has a messages array which holds Messages. Each Message has both a dateSent property and a dateViewed property. The Message items are embedded, not referenced.
How can I sort Chats by most recent not viewed Message (ie, empty dateViewed) first and then by dateSent? (think Facebook Messenger behavior...)
This is what I've tried so far (note that Chat also has a users array):
Chat.find({users._id: userId}).sort({messages.dateViewed: -1, messages.dateSent: -1}).exec(function(err, chats){
// handle err
// handle no docs found
// handle docs found
});
The above does not seem to work, as the Chats come out in a different order (the same as without sort()). Any thoughts?
EDIT: The suggested answer didn't help me because I don't want to sort the Message objects in the message array, but rather sort the Chats resulting from the query, by the dates in the Message object they hold in a messages array.
The Aggregation pipeline should be used in order to achieve the required sort.
chats/messages:
> db.chats.find()
{ "_id" : "c1", "messages" : [ { "_id" : "m1_1", "dv" : -1, "ds" : 9000 }, { "_id" : "m1_2", "dv" : 8010, "ds" : 8000 } ] }
{ "_id" : "c2", "messages" : [ { "_id" : "m2_1", "dv" : -1, "ds" : 11000 } ] }
{ "_id" : "c3", "messages" : [ { "_id" : "m3_1", "dv" : -1, "ds" : 700 }, { "_id" : "m3_2", "dv" : 7010, "ds" : 7000 } ] }
The code to sort the data by the give criteria:
db.chats.aggregate([
{ $unwind: '$messages' },
{ $addFields: {
ts: {
$cond: [
{ $eq: ['$messages.dv', -1 ] },
'$messages.ds',
'$messages.dv']
}
}
},
{
$sort: { 'ts': -1 }
},
{
$group: {
_id: '$_id',
ts: { $max: '$ts'},
messages: { $push: '$messages' }
}
},
{
$sort: {ts: -1}
}]);
The results:
{ "_id" : "c2", "ts" : 11000, "messages" : [ { "_id" : "m2_1", "dv" : -1, "ds" : 11000 } ] }
{ "_id" : "c1", "ts" : 9000, "messages" : [ { "_id" : "m1_1", "dv" : -1, "ds" : 9000 }, { "_id" : "m1_2", "dv" : 8010, "ds" : 8000 } ] }
{ "_id" : "c3", "ts" : 7010, "messages" : [ { "_id" : "m3_2", "dv" : 7010, "ds" : 7000 }, { "_id" : "m3_1", "dv" : -1, "ds" : 700 } ] }

Remove entry from double nester array using mongoose

I'm trying to remove an entry from an array which nested in another array as you can see below:
{
"_id" : ObjectId("548f5ca9fa9dc1000016a725"),
"entries" : [
{
"_id" : ObjectId("548f5cc8fa9dc1000016a726"),
"content" : [
{
"order" : ObjectId("5489fa9127f1310000bea2ed"),
"order_id" : "305429245",
"item_id" : "305429245-1"
},
{
"order" : ObjectId("5489fa9127f1310000bea2ce"),
"order_id" : "330052901",
"item_id" : "330052901-1"
}
],
"stop_number" : 1
},
{
"stop_number" : 2,
"expected_arrival" : ISODate("2014-12-15T17:11:11.000Z"),
"expected_departure" : ISODate("2014-12-15T19:03:17.000Z"),
"_id" : ObjectId("548fb2826e52c20000bd2299"),
"content" : []
}
]
}
And i'm trying to remove the entry that have '305429245-1', so i used:
Q.npost(Manifests, 'findOneAndUpdate', [
{ '_id': id },
{
'$pull': {
'entries.content': { item_id: line_item_id }
}
}
])
where 'id' is the ObjectID (548f5ca9fa9dc1000016a725) and line_item_id = 305429245-1, however, this doesn't work. Can anyone let me know what am i doing wrong?
Try to use find and Update functions separately instead of findOneAndUpdate
Model.find({'_id: id'},function(err,callback){...})
{
//handle callback
}
Model.update({'_id: id'}, {$pull: {'entries.content': item_id: line_item_id}}, function(err,callback){..} )
{
//do some logic or handle callback
}
here Model which i mentioned,should be the model you are using.

Resources