How to add a particular value for all records in the collection using aggregation - mongodb

How to add a particular value for all records in the collection using aggregation :
Have a collection with data :
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas",
date:2019-11-25T01:00:00.000+00:00
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
age: 45,
location: "texas",
date:2019-11-25T01:00:00.000+00:00
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
age: 69,
location: "texas",
date:2019-11-25T01:00:00.000+00:00
}
]
if date column exists for any of the records present_working:true should be added in the collection for the records
expected output:
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas",
date:2019-11-25T01:00:00.000+00:00
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
present_working:true,
age: 45,
location: "texas",
date:2019-11-25T01:00:00.000+00:00
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
present_working:true,
age: 69,
location: "texas",
date:2019-11-25T01:00:00.000+00:00
}
]

There is no need to use aggregation for this.
You can do it simply this way:
collection.updateMany({
date: {
$exists: true
}
}, {
$set: {
present_working: true
}
})
If you want to do it with the aggregation framework:
collection.aggregate(
[
{
"$match" : {
"date" : {
$exists: true
}
}
},
{
"$addFields" : {
"present_working" : true
}
}
]
)

So if you wanted to return conditionally add a field based upon existence of other field in aggregation while reading data from database then try below query :
/** If `date` exists then it will add the field & assign value to true else `$$REMOVE` will help to not add the field at all,
* Additionally if you're ok to add this new field for docs where `date : null` then replace `$gt` with `$gte` */
db.collection.aggregate([
{
$addFields: {
present_working: { $cond: [ { "$gt": [ "$date", null ] }, true, "$$REMOVE" ] }
}
}
])
Test : mongoplayground
Ref : aggregation-pipeline

Related

Field combination in an array where another field is the same in MongoDB?

I want to find matches with the same gender and insert them into a new field array aka names but I am unable to solution using MongoDB. Or mongooese.
Input example:
db.students.insertMany([
{ id: 1, name: "Ryan", gender: "M" },
{ id: 2, name: "Joanna", gender: "F" },
{ id: 3, name: "Andy", gender: "M" },
{ id: 4, name: "Irina", gender: "F" }
]);
Desired output:
[
{ gender: "M", names: ["Ryan","Andy"]},
{ gender: "F", names: ["Joanna","Irina"]}
]
Note: the table has many records and I do not know those gender/name pairs in advance
I try this but no results. I don't know how I should write this query.
db.students.aggregate([
{
$group:{
names : {$push:"$name"},
}
},
{ "$match": { "gender": "$gender" } }
])
You did not specify how to group. Try this one:
db.students.aggregate([
{
$group: {
_id: "$gender",
names: { $push: "$name" }
}
},
{
$set: {
gender: "$_id",
_id: "$$REMOVE"
}
}
])

Remove a particular field for all documents in a collection using aggregation in mongoDB

How to Remove a particular value for all records in the collection using aggregation :
Have a collection with data :
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas"
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
age: 45,
present_working:false,
location: "texas"
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
age: 69,
location: "texas",
present_working:false
}
]
Remove the rows in records for which there is present_working:false. Data need not be removed in the database, it should be only modified in the aggregation pipeline
Expected output after removing only present_working:false and present_working:false should be kept in database. :
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas"
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
age: 45,
location: "texas"
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
age: 69,
location: "texas"
}
]
MongoDB version: 4.0
You can use $$REMOVE as part of $project:
db.collection.aggregate([
{
$project: {
_id: 1,
name: 1,
occupation: 1,
age: 1,
location: 1,
present_working: { $cond: [ { $eq: [ "$present_working", false ] }, "$$REMOVE", "$present_working" ] }
}
}
])
Mongo Playground

Remove a particular field for all documents in a collection using MongoDB aggregation

How to Remove a particular value for all records in the collection using aggregation :
Have a collection with data :
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas",
date:2019-11-25T10:49:36.534+00:00
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
age: 45,
present_working:true,
location: "texas",
date:null
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
age: 69,
location: "texas",
date:null
}
]
Remove the rows in records for which there is date:null. Data need not be removed in the database, it should be only modified in the aggregation pipeline
Expected output after removing only date:null :
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas",
date:2019-11-25T10:49:36.534+00:00
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
age: 45,
present_working:true,
location: "texas"
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
age: 69,
location: "texas"
}
]
MongoDB version: 4.0
You can use $ifNull operator & $$REMOVE to do that :
db.collection.aggregate([
{
$addFields: {
date: {
$ifNull: [
"$date",
"$$REMOVE"
]
}
}
}
])
Test : MongoDB-Playground

Add date to all records in a collection in ascending order using mongodb aggregation pipeline

is it possible in aggregation to add dates for all records from a particular date
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas",
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
age: 45,
present_working:true,
location: "texas",
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
age: 69,
location: "texas",
}
]
is there a way to add dates for all records from this date date:2019-11-25T01:00:00.000+00:00 in ascending order like this
[
{
_id: "bmasndvhjbcw",
name: "lucas",
occupation: "scientist",
present_working:true,
age: 55,
location: "texas",
date:2019-11-25T01:00:00.000+00:00
},
{
_id: "bmasndvhjbcx",
name: "mark",
occupation: "scientist",
age: 45,
present_working:true,
location: "texas",
date:2019-11-26T01:00:00.000+00:00
},
{
_id: "bmasndvhjbcq",
name: "cooper",
occupation: "physicist",
age: 69,
location: "texas",
date:2019-11-27T01:00:00.000+00:00
}
]
mongodb version 4.0
You can achieve this with the following query :
db.collection.aggregate([
{
$group: {
_id: null,
docs: {
$push: "$$ROOT"
}
}
},
{
$unwind: {
path: "$docs",
includeArrayIndex: "index"
}
},
{
$addFields: {
"docs.date": {
$add: [
{
$dateFromString: {
dateString: "2019-11-25T01:00:00.000"
}
},
{
$multiply: [
"$index",
{
$multiply: [
24,
60,
60,
1000
]
}
]
}
]
}
}
},
{
$replaceRoot: {
newRoot: "$docs"
}
}
])
Test it here
This aggregation gets the expected result:
THIS_DATE = ISODate("2019-11-25T01:00:00.000+00:00")
db.collection.aggregate( [
{
$group: {
_id: null,
docs: { $push: "$$ROOT" }
}
},
{
$project: {
_id: 0,
docs: {
$map: {
input: { $range: [ 0, { $size: "$docs" } ] },
in: {
$mergeObjects: [
{ date: { $add: [ THIS_DATE, { $multiply: [ "$$this", 24*60*60*1000 ] } ] } },
{ $arrayElemAt: [ "$docs", "$$this" ] }
]
}
}
}
}
},
{
$unwind: "$docs"
},
{
$replaceRoot: { newRoot: "$docs" }
}
] )

MongoDB .Need to count fileds of an array

I have a collection like below
{ _id: 1, zipcode: "63109", students: [
{ name: "john", school: 102, age: 10 },
{ name: "jess", school: 102, age: 11 },
{ name: "jeff", school: 108, age: 15 }
] }
{ _id: 2, zipcode: "63110", students: [
{ name: "ajax", school: 100, age: 7 },
{ name: "achilles", school: 100, age: 8 },
] }
{ _id: 3, zipcode: "63109", students: [
{ school: 100, age: 7 },
{ school: 100, age: 8 },
] }
{ _id: 4, zipcode: "63109", students: [
{ name: "barney", school: 102, age: 7 },
{ name: "ruth", school: 102, age: 16 },
] }
Note:Some document doesnot have name field.
I want to findout the count of name field.
Kindly suggest query to find count in mongo
You can do this with aggregation framework with $unwind. Let say your collection name is test:
db.test.aggregate(
{$unwind: '$students'},
{$match:{'students.name':{$exists:1}}},
{$group:{_id: '$students.name', count:{$sum:1}}},
{$project:{tmp:{name:'$_id', count:'$count'}}},
{$group:{_id:'Total Names', total:{$sum:1}, data:{$addToSet:'$tmp'}}}
)
Hope this is what you want!
You need to use the aggregation framework in this case.
The first aggregation step would be to use $unwind to turn the arrays into streams of documents.
Then you can use $group as a second aggregation step with $sum:1 to get the count of every name.
db.collection.aggregate([
{
$unwind: "$students"
},
{
$group: {
_id:"$students.name",
count: { $sum:1 }
}
}
]
This is doable through the aggregation framework
I'll assume your collection is called mycoll:
db.mycoll.aggregate([
{$unwind:'$students'},
{$group:{_id:'$name', 'count':{$sum:1}},
{$match:{'students.name':{$exists:1}}}
]);
References:
Aggregations http://docs.mongodb.org/manual/tutorial/aggregation-zip-code-data-set/
Exists: http://docs.mongodb.org/manual/reference/operator/query/exists/
Summing '1' essentially turns it into a count.