mongodb how to project first child - mongodb

I got a mongo db collection with structure
randomstring - means the string is actually random its diffrent in each document of the collection.
{
"notrandom":{
"randomstring":{
"randomstring":{
"randomstring":{
"notrandom2":"data"
}
}
}
}
}
how can i project this data out?
something like
db.mydb.aggregate( "notrandom[0][0].notrandom2":1}} , ] )
what i'm trying to achieve is a collection of all the notrandom2 values.

if you you to move notrandom2 to higer level in document structure,
you could use $project stage like this:
{
$project:{
_id:1,
notrandom2:"notrandom.randomstring.randomstring.randomstring.notrandom2",
// list all others fields with field:1 if you want them to appear down in pieline
}}
if this field is a part of an array then you need to $unwind first and then $project

You can use the following query
db.mydb.find({<findquery (in you have any)>},{"notrandom.randomstring.randomstring.randomstring.notrandom2" : 1}).
toArray(function(err, result)
{
console.log(result); //Array of objects with `notrandom2` values
})

Related

Mongo adding a field to a specific object in an array of objects using updateOne during a bulkUpdateOps

Use case
Adding a field to a specific object in an array of objects using updateOne during a bulkUpdateOps
Blockers
I have been unable to find a way to identify and update a specific object in the subdocument array of a specific record.
I only have access to this DB through MongoDB Compass, and I plan to use the provided mongosh tool.
Data example
Our purchaseorders model looks like this:
{
_id: uuid,
...rest,
documents:[
{
_id:uuid,
forignKey2:string (optional),
keyIWantToAdd:string (optional),
...rest
}
]
}
So if I have
{
_id:*1,
documents:[
{
_id:*2,
forignKey2:'no-test',
...rest
},
{
_id:*3,
forignKey2:'test',
...rest
},
]
}
I want to add a key and value like this (really I'm willing to do anything to set these values, this is just the closest I have been able to get):
var bulkUpdateOps = db.purchaseorders.initializeOrderedBulkOp();
bulkUpdateOps.find('*1').updateOne({
$set:{
documents.[index of document object with forignKey2:'test' or _id:*3 whichever is easier].keyIWantToAdd:'valueIWantToAdd'
}
})
bulkUpdateOps.execute();
Any help or suggestions would be greatly appreciated.
#rickhg12hs posted exactly what I was looking for. For anyone else using mongodb.com/docs/manual/reference/method/Bulk.find.arrayFilters the bulk find is being ran on an array of objects like this: { grades:[ { grade: 85, mean: number } ] }

Mongodb: multiple objects in an array

I am new to Mongodb and I have been assigned a task to extract data from mongoDB and create a csv and load it to Oracle database. Below is the data in Mongodb
{{
"_id":"69ajdslsdfdksjfef9",
"col1":"456780",
"refNum":"ref001"
}
{
"clients":{
"CLI_1": "9876547390",
"CLI_2": "fsdfasl"
}
{"names":[
{
"first":"dfsakfj",
"middle":"hgfgas",
"last":"komdssdfsd"
},
{
"first":"dfskdajf",
"middle": "fgjfgjfl",
"last": "ghfghsdklfg"
}]}
second row from collection
{{
"_id":"69ajdslsdfdksjfef9",
"col1":"456780",
"refNum":"ref001"
}
{
"clients":{
"CLI_1": "9876547390",
"CLI_2": "fsdfasl"
}
{"names":[
{
"first":"dfsakfj",
"middle":"hgfgas",
"last":"komdssdfsd"
}]}
I am using pymongo utility to query and create a dataframe before generating the csv file. However, I am able to create a dataframe but not able parse "names" properly as it is inconsistent when compared between the rows. Could anyone please share how to parse and create a csv with fields _id, first, middle, last
Thank You
There is mongodb aggregation pipeline named $unwind which can help you with the task to flatten the names array so it is suitable for csv output as follow:
db.collection.aggregate([
{
$unwind: "$names"
},
{
$project: {
_id: 1,
first: "$names.first",
middle: "$names.middle",
last: "$names.last"
}
}
])// _id, first, middle, last
playground

MongoDB : Match with element in an array

I am working on a collection called Publications. Each publication has an array of objectives which are ids. I have also a custom array of objectives hand written. Now, I want to select all the publications that contains at least one element of the custom objectives array in their objectives. How can I do that ?
I've been trying to make this works with '$setIntersection' then '$count' and verify that the count is greater than 0 but I don't know how to implement this.
Example :
publication_1: {
'_id': ObjectId("sdfsdf46543")
'objectives': [ObjectId("1654351456341"), ObjectId("123456789")]
}
publication_2: {
'_id': ObjectId("sdfs216546543")
'objectives': [ObjectId("1654351456341"), ObjectId("46531132")]
}
custom_array = [ObjectId("123456789"), ObjectId("2416315463")]
The mongo query should return publication_1.
You can do like the following:
db.publications.find({
"objectives": {
"$in": [
ObjectId("123456789"),
ObjectId("2416315463")
]
}
})
Notice: "123456789" is not a valid ObjectId so the query itself may not work. Here is the working example
Mongodb playground link: https://mongoplayground.net/p/MbZK99Pd5YR
objectives is an array of objects, I guess you can just query that field directly:
let custom_array = [ObjectId("123456789"), ObjectId("2416315463")];
// You can search the array with $in property.
let result = await Model.find({ objectives: {$in : custom_array} })

Mongoose Updating an array in multiple documents by passing an array of filters to update query

I have multiple documents(3 documents in this example) in one collection that looks like this:
{
_id:123,
bizs:[{_id:'',name:'a'},{_id:'',name:'b'}]
},
{
_id:456,
bizs:[{_id:'',name:'e'},{_id:'',name:'f'}]
}
{
_id:789,
bizs:[{_id:'',name:'x'},{_id:'',name:'y'}]
}
Now, I want to update the bizs subdocument by matching with my array of ids.
That is to say, my array filter for update query is [123,789], which will match against the _id fields of each document.
I have tried using findByIdAndUpdate() but that doesn't allow an array for the update query
How can I update the 2 matching documents (like my example above) without having to put findByIdAndUpdate inside a forloop to match the array element with the _id?
You can not use findByIdAndUpdate when updating multiple documents, findByIdAndUpdate is from mongoose which is a wrapper to native MongoDB's findOneAndUpdate. When you pass a single string as a filter to findByIdAndUpdate like : Collection.findByIdAndUpdate({'5e179dac627ef7823643cd97'}, {}) - then mongoose will internally convert string to ObjectId() & form it as a filter like :_id : ObjectId('5e179dac627ef7823643cd97') to execute findOneAndUpdate. So it means you can only update one document at a time, So if you've multiple documents to be updated use update with option {multi : true} or updateMany.
Assume if you wanted to push a new object to bizs, this is how query looks like :
collection.updateMany({ _id: { $in: [123, 456] } }, {
$push: {
bizs: {
"_id": "",
"name": "new"
}
}
})
Note : Update operations doesn't return the documents in response rather they will return write result which has information about n docs matched & n docs modified.

Removing documents from one mongo collection that are matched in another collection

This may be a noobie question but, how do I (efficiently) remove all documents from one mongodb collection that match documents found in another collection? For example, using mongo shell, we could do the following:
db.getCollection('coll1').find({}).forEach( function(doc) {
db.getCollection('coll2').remove( { name: doc.name, value: doc.value } );
})
I will suggest to do it using $in with remove by passing array of name or Id's in $in array with remove.
db.getCollection('coll1').find({}).forEach( function(doc) {
// create idsArray from the doc data and pass same in $in
db.getCollection('coll2').remove({ id: { $in: idsArray });
})
I hops it will help. :)