sort a collection based on multiple fields in mongodb - mongodb

I've a requirement where I need to sort the collection based on different fields. Below is my db entry
db.requests.find()
{ "_id" : ObjectId("5caf805f50ca58361589924b"),"type" : "adhoc", "immediate" : false, "place": "london"}
{ "_id" : ObjectId("5c947e37015bfe78a80e5349"),"type" : "adhoc", "immediate" : true, "place": "tokoy" }
{ "_id" : ObjectId("5c9481fa015bfe78a80e534d"),"type" : "periodic", "immediate" : false , "place": "bangalore"}
{ "_id" : ObjectId("5c94ae95015bfe78a80e5363"),"type" : "adhoc", "immediate" : true, "place": "lanka"}
{ "_id" : ObjectId("5c875a96015bfe7b5e772ea3"),"type" : "adhoc", "immediate" : false, "place": "jakarta"}
{ "_id" : ObjectId("5c9481fa015bfe78a80e534d"),"type" : "periodic", "immediate" : false , "place": "europe"}
considering
If "type" is "adhoc" then "immediate" can be either "true" or "false".
If "type" is "periodic" then "immediate" will always be "false"
I just want to have result in the below order:
all entries with "immediate" : "true"
all entries with "type": "adhoc" and "immediate": "false"
all entries with "type":"periodic"
Result should be like:
{ "_id" : ObjectId("5c947e37015bfe78a80e5349"),"type" : "adhoc", "immediate" : true, "place": "tokoy" }
{ "_id" : ObjectId("5c94ae95015bfe78a80e5363"),"type" : "adhoc", "immediate" : true, "place": "lanka"}
{ "_id" : ObjectId("5caf805f50ca58361589924b"),"type" : "adhoc", "immediate" : false, "place": "london"}
{ "_id" : ObjectId("5c875a96015bfe7b5e772ea3"),"type" : "adhoc", "immediate" : false, "place": "jakarta"}
{ "_id" : ObjectId("5c9481fa015bfe78a80e534d"),"type" : "periodic", "immediate" : false , "place": "bangalore"}
{ "_id" : ObjectId("5c9481fa015bfe78a80e534d"),"type" : "periodic", "immediate" : false , "place": "europe"}

Related

MongoDB Add new field to each element of array

I have a mongo collection myCollection with the following structure :
{ "_id" : ObjectId("xxxxxxx"),
"name" : "name1",
"address" : "address1",
"list" : [
{ "field1" : true,
"field2" : false
},
{ "field1" : true,
"field2" : false
}]
},
...
,
{ "_id" : ObjectId("zzzzzzzzz"),
"name" : "name100",
"address" : "address100",
"list" : [
{ "field1" : true,
"field2" : false
},
{ "field1" : true,
"field2" : true
}]
}
For each document of the collection, I would like to create a new field (field3) with the default value false for each subelement of the array list.
Expected output :
{ "_id" : ObjectId("xxxxxxx"),
"name" : "name1",
"address" : "address1",
"list" : [
{ "field1" : true,
"field2" : false,
"field3" : false
},
{ "field1" : true,
"field2" : false,
"field3" : false
}]
},
...
,
{ "_id" : ObjectId("zzzzzzzzz"),
"name" : "name100",
"address" : "address100",
"list" : [
{ "field1" : true,
"field2" : false,
"field3" : false
},
{ "field1" : true,
"field2" : true,
"field3" : false
}]
}
You can use $addFields to add more fields
db.collection.aggregate([
{
$addFields: {
"list.fields3": false
}
}
])
Working Mongo Playground

Why mongodb arbiter needs dbpath?

An mongodb arbiter roles are as follows:
An arbiter does not have a copy of data set and cannot become a primary. However, an arbiter participates in elections for primary. An arbiter has exactly 1 election vote.
Arbiters are mongod instances that are part of a replica set but do not hold data. Then, why arbiter needs dbpath?
The arbiter stores various housekeeping data, which you can inspect by looking at the local database:
MongoDB Enterprise ruby-driver-rs:ARBITER> db.getMongo().setSlaveOk()
MongoDB Enterprise ruby-driver-rs:ARBITER> use local
switched to db local
MongoDB Enterprise ruby-driver-rs:ARBITER> db.runCommand({listCollections:1})
{
"cursor" : {
"id" : NumberLong(0),
"ns" : "local.$cmd.listCollections",
"firstBatch" : [
{
"name" : "system.replset",
"type" : "collection",
"options" : {
},
"info" : {
"readOnly" : false,
"uuid" : UUID("108fbabe-4139-4d3d-8326-fc8e169b811d")
},
"idIndex" : {
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
}
},
{
"name" : "startup_log",
"type" : "collection",
"options" : {
"capped" : true,
"size" : 10485760
},
"info" : {
"readOnly" : false,
"uuid" : UUID("1c3ed741-a7f8-4fad-89f9-36f979cbfa22")
},
"idIndex" : {
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
}
},
{
"name" : "replset.oplogTruncateAfterPoint",
"type" : "collection",
"options" : {
},
"info" : {
"readOnly" : false,
"uuid" : UUID("37c4d64b-8fcc-4aa5-b1e0-2ac6b71e893a")
},
"idIndex" : {
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
}
},
{
"name" : "replset.election",
"type" : "collection",
"options" : {
},
"info" : {
"readOnly" : false,
"uuid" : UUID("53fc68a9-19c9-4262-b152-fafa99ea55f5")
},
"idIndex" : {
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
}
},
{
"name" : "replset.minvalid",
"type" : "collection",
"options" : {
},
"info" : {
"readOnly" : false,
"uuid" : UUID("5564332b-3c3f-4103-acbd-c53c7a71581c")
},
"idIndex" : {
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
}
},
{
"name" : "system.rollback.id",
"type" : "collection",
"options" : {
},
"info" : {
"readOnly" : false,
"uuid" : UUID("fa26f83a-8843-4b6d-8d4d-4cde192976bd")
},
"idIndex" : {
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
}
}
]
},
"ok" : 1
}

Update query on in the collection by "_id"

{
"_id" : "tenant/data/EMAIL/ENGLISH",
"tenantId" : "tenant2",
"channelType" : "EMAIL",
"template" : [
{
"_id" : "1",
"templateName" : "abc",
"effectiveStartDate" : ISODate("2017-01-01T12:00:00.000Z"),
"modifiedDate" : ISODate("2017-06-02T22:08:55.782Z"),
"active" : false
}
]
}
I need to update the "templateName" : "xyz" on the basis of "_id" : "tenant/data/EMAIL/ENGLISH"
I have tried these queries but got no success
db.getCollection('data').updateOne({"_id": "tenant/data/EMAIL/ENGLISH"},
{$set : { "template.$.templateName" : "XYZ"}}); 
db.getCollection('data').updateOne({"_id": "tenant/data/EMAIL/ENGLISH"},
{$set : { "template.templateName" : "XYZ"}}); 
Any help will be appreciated.
I have used positional-all operator to update the array.
Here is the query:
db.sample.update(
{
"_id": "tenant/data/EMAIL/ENGLISH"
},
{
$set:{
"template.$[].templateName":"XYZ"
}
}
)
Output
{
"_id" : "tenant/data/EMAIL/ENGLISH",
"tenantId" : "tenant2",
"channelType" : "EMAIL",
"template" : [
{
"_id" : "1",
"templateName" : "XYZ",
"effectiveStartDate" : ISODate("2017-01-01T12:00:00Z"),
"modifiedDate" : ISODate("2017-06-02T22:08:55.782Z"),
"active" : false
}
]
}
hope this will help :)

mongodb update single object in array

How to update Single object in array of objects by rules query is that object must by in document that has translation_key == as input that i read and object must have same language (id) if not i must create new object . ( mongodb, mongoose)
Language are required and uniueq in translations
{
"_id" : ObjectId("5bfd5324725fb12bc4863cd8"),
"deleted" : false,
"deleted_at" : null,
"noAuth" : false,
"hidden" : false,
"translation_key" : "Standard",
"translation_type" : "text",
"translation" : [
{
"system" : {
"android" : false,
"ios" : false,
"web" : false,
"api" : false
},
"language" : ObjectId("5bf52e06edb9902e2113d8b3"),
"text":'',
"active" : false,
"prepared_string" : false,
"_id" : ObjectId("5bfd910c2998d929644abd90"),
"params" : []
},
{
"system" : {
"android" : false,
"ios" : false,
"web" : true,
"api" : false
},
"active" : false,
"prepared_string" : false,
"_id" : ObjectId("5bfdb5d22998d929644ac2af"),
"language" : ObjectId("5bf52e06edb9902e6471d8c1"),
"text" : "Standard",
"app_version" : "2.0",
"params" : []
}
],
"create_date" : ISODate("2018-11-27T14:22:28.635Z"),
"update_date" : ISODate("2018-11-27T14:22:28.635Z"),
"__v" : 3
}
Model.findOneAndUpdate(
{
_id: "document_id",
"translation.language": "languageId",
},
{
$set: {
"translation.$.text: "text",
"translation.$.active": "status",
"translation.$.system.android" : true
},
{ new: true, upsert: true, }
)
.lean();

Update attribute value in nested array

My collection named user have 6 fields. Profile field is document. It have only array named Packages. Packages is collection of documents, which contains all packages current user have.
My database is like:
{
"_id" : "AayujR3SLT5MtmTKf",
"createdAt" : ISODate("2015-09-18T07:19:05.069Z"),
"services" : {
"password" : {
"bcrypt" : "encripted_password_here"
}
},
"username" : "test_user",
"emails" : [{
"address" : "1#gmail.com",
"verified" : false
}],
"profile" : {
"packages" : [{
"packageId" : "67fmCMNTdqejFs7NE",
"name" : "package1"
"active" : true
}, {
"packageId" : "Dcn4PkmHNe8APuk73",
"name" : "package2"
"active" : true
}, {
"packageId" : "yvdXkPeNHEWwwLKjC",
"name" : "package2"
"active" : true
}]
}
}
I want set all active to false. What should I do? My current code is like (not working):
Meteor.users.update({ _id: Session.get('user_id') }, { $set: {'profile.packages.active': false} });
It cannot be done in a single query as there are many elements in the "packages" array. Even if you try the below query, only the first match will get updated in the current document and rest will remain same.
db.exp10.update({"profile.packages.active":true},{$set:{"profile.packages.$.active":false}},{multi:true})
Output :
{
"_id" : "AayujR3SLT5MtmTKf",
"createdAt" : ISODate("2015-09-18T07:19:05.069Z"),
"services" : {
"password" : {
"bcrypt" : "encripted_password_here"
}
},
"username" : "test_user",
"emails" : [
{
"address" : "1#gmail.com",
"verified" : false
}
],
"profile" : {
"packages" : [
{
"packageId" : "67fmCMNTdqejFs7NE",
"name" : "package1",
"active" : false
},
{
"packageId" : "Dcn4PkmHNe8APuk73",
"name" : "package2",
"active" : true
},
{
"packageId" : "yvdXkPeNHEWwwLKjC",
"name" : "package2",
"active" : true
}
]
}
}
So better we can do it using the below piece of code :
db.user.find({"profile.packages.active":true}).forEach(function(doc){
for( var count = 0; count < doc.profile.packages.length; count++ )
{
if( doc.profile.packages[count].active == true )
doc.profile.packages[count].active = false;
}
db.user.save(doc);
});
Output :
{
"_id" : "AayujR3SLT5MtmTKf",
"createdAt" : ISODate("2015-09-18T07:19:05.069Z"),
"services" : {
"password" : {
"bcrypt" : "encripted_password_here"
}
},
"username" : "test_user",
"emails" : [
{
"address" : "1#gmail.com",
"verified" : false
}
],
"profile" : {
"packages" : [
{
"packageId" : "67fmCMNTdqejFs7NE",
"name" : "package1",
"active" : false
},
{
"packageId" : "Dcn4PkmHNe8APuk73",
"name" : "package2",
"active" : false
},
{
"packageId" : "yvdXkPeNHEWwwLKjC",
"name" : "package2",
"active" : false
}
]
}
}
P.S :
If the collection has many documents, For better performance we can use Bulk Operations.