MongoDB querying nested documents - mongodb

I have records like:
{
"_id" : ObjectId("5f99cede36fd08653a3d4e92"),
"accessions" : {
"sample_accessions" : {
"5f99ce9636fd08653a3d4e86" : {
"biosampleAccession" : "SAMEA7494329",
"sraAccession" : "ERS5250977",
"submissionAccession" : "ERA3032827",
"status" : "accepted"
},
"5f99ce9636fd08653a3d4e87" : {
"biosampleAccession" : "SAMEA7494330",
"sraAccession" : "ERS5250978",
"submissionAccession" : "ERA3032827",
"status" : "accepted"
}
}
}
}
How do I query by the mongo id in sample_accessions? I thought this should work but it doesn't. What should I be doing?
db.getCollection('collection').find({"accessions.sample_accessions":"5f99ce9636fd08653a3d4e86"})

The id is a key and check whether key is exists or not use $exists, customize response using project to get specific object
db.getCollection('collection').find(
{
"accessions.sample_accessions.5f99ce9636fd08653a3d4e86": {
$exists: true
}
},
{ sample_doc: "$accessions.sample_accessions.5f99ce9636fd08653a3d4e86" }
)
Playground

Related

MongoDB - Update an Key

I have been trying to update an Object for this collection. Below is the collection. Looking for Server 3.6 version.
Here The ask is Need to update the class name from "HISTORY" to " HISTORY_NEW". Need to do, for some students in the class. Need a query that will select all student records in student collection with "HISTORY" class in it and update them to "HISTORY_NEW ". I have around 30,000 records and not getting a bulk update method.
{
"_id" : ObjectId("611f90aa43f77a728879c395"),
"studentId" : "stu1",
"classes" : {
"History" : {
"TeacherName" : "T1",
"Marks" : [
{
"Internal": 15
}
]
},
"Geography" : {
"TeacherName" : "T2",
"Marks" : [
{
"Internal" : 20
}
]
}
},
"updateDate" : ISODate("2021-10-12T11:40:47.156Z")
}
This is the result I am expecting
{
"_id" : ObjectId("611f90aa43f77a728879c395"),
"studentId" : "stu1",
"classes" : {
"HISTORY_NEW" : {
"TeacherName" : "T1",
"Marks" : [
{
"Internal": 15
}
]
},
"Geography" : {
"TeacherName" : "T2",
"Marks" : [
{
"Internal" : 20
}
]
}
},
"updateDate" : ISODate("2021-10-12T11:40:47.156Z")
}
.Or is that even possible with the kind of collection above or going via code route?
So far this is what I have, without any success.
Get all students' Ids and then update the Class name. But that is also not working and don't think it is smart to update DB 30,000 times.
var studentIds =[];
db.studentSubject.find({"classes.History":{$exists:true}})
.forEach(function(u) { studentIds.push(u.studentId) })
studentIds.forEach(function(studentId) {
var result;
try {
result =db.studentSubject.updateOne(
{studentId:studentId},
{ $set : {"classes.History": "HISTORY_NEW",}},
{ upsert: false});
} catch (e) {
print(e);
}
});
From your scenario, you need $rename operator.
As discussed in the comment, you don't need to fetch each document to get studentId and then pass it to update each document. Just bulk update by checking the document has classes.History field.
db.collection.update({
"classes.History": {
$exists: true
}
},
{
$rename: {
"classes.History": "classes.HISTORY_NEW"
}
},
{
upsert: false,
multi: true
})
Sample Mongo Playground

How to set value from different field or collection from specific document in Mongo shell

I have colection "ttn_data" with doc:
{
"_id" : ObjectId("Some_different_ID"),
"dev_id" : "e0e1e20102030405",
"payload_fields" : {"temp_C" : 28.308}
}
and collection "records" with doc
{
"_id" : ObjectId("5ed8af72c377d5b209597981"),
"temp_C_different" : ""
}
I would like to set temp_C_different value from temp_C in ttn_data collection so the return after update query would be
{
"_id" : ObjectId("5ed8af72c377d5b209597981"),
"temp_C_different" : "28.308"
}
I try this method:
try { db.records.updateMany( { "_id" : ObjectId("5ed8af72c377d5b209597981") },
{ $set: { "temp_C_different" : db.ttn_data.temp_C.value } } ); }
catch (e) { print(e); }
but it sets "temp_C_different"value to some metadata info from database. What is the write way to do that kind of update?

Update a json document in a mongodb database

I'm trying to update an existing document in a MongoDb. There are many explanations how to do this if you want to update or add key/value pairs on the first level. But in my use-case, I need to create with the first updateOne (with upsert option set) a document with the following structure:
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
}
}
}
}
In the second command, I need to add - in the same document - a "meas2" field at the level of "meas1". My desired output is:
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
},
"meas2" : {
"data" : "foo"
}
}
}
}
I played with statements like
updateOne({"_id":"1234"},{$set:{"raw":{"meas":{"meas2":{"data":"foo"}}}}}, {"upsert":true})
and also with $push, both variants with insert - here only the document and also insertOne, but nothing produces the desired output. Is there a MongoDb expert who could give a hint ? ... I'm sure this functionality exists... Thanks in advance!
When you update {$set: {"raw":{"meas":{"meas2":{"data":"foo"}}}} you're not adding "mesa2" to "meas" but rather you're overriting "raw" completely.
In order to change / add one field in a document refer to it with dot notations.
The command you want is updateOne({"_id": "1234"}, {$set: {"raw.meas.mesa2": { "data" : "foo" }}}, {"upsert":"true"})
You need to understand the below concept first
Set Fields in Embedded Documents, with details document check at official documentation of mongo
For your problem, just look at the below execution on the mongo shell:
> db.st4.insert({
... "_id" : "1234",
... "raw" : {
... "meas" : {
... "meas1" : {
... "data" : "blabla"
... }
... }
... }
... })
WriteResult({ "nInserted" : 1 })
> db.st4.find()
{ "_id" : "1234", "raw" : { "meas" : { "meas1" : { "data" : "blabla" } } } }
>
> // Below query will replace the raw document with {"meas":{"meas2":{"data":"foo"}}}, will not add
> //db.st4.updateOne({"_id":"1234"},{$set:{"raw":{"meas":{"meas2":{"data":"foo"}}}}}, {"upsert":true})
>// By using the dot operator, you actually write the values inside the documents i.e you are replacing or adding at raw.meas.mesa2 i.e inside the document of mesa2.
> db.st4.updateOne({"_id":"1234"},{$set: {"raw.meas.mesa2": { "data" : "foo" }}}, {"upsert":"true"})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.st4.find().pretty()
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
},
"mesa2" : {
"data" : "foo"
}
}
}
}
>

Mongo query to return distinct count, large documents

I need to be able to get a count of distinct 'transactions' the problem I'm having is that using .distinct() comes back with an error because the documents too large.
I'm not familiar with aggregation either.
I need to be able to group it by 'agencyID' as you see below there are 2 different agencyID's
I need to be able to count transactions where the agencyID is 01721487 etc
db.myCollection.distinct("bookings.transactions").length
this doesn't work as I need to be able to group by agencyID and if there are too many results I get an error saying it's too large.
{
"_id" : ObjectId("5624a610a6e6b53b158b4744"),
"agencyID" : "01721487",
"paxID" : "-530189664",
"bookings" : [
{
"bookingID" : "24232",
"transactions" : [
{
"tranID" : "001",
"invoices" : [
{
"invNum" : "1312",
"type" : "r",
"inv_date" : "20150723",
"inv_time" : "0953",
"inv_val" : -300
}
],
"tranType" : "Fee",
"tranDate" : "20150723",
"tranTime" : "0952",
"opCode" : "admin",
"udf_1" : "j s"
}
],
"acctID" : "acct11",
"agt_id" : "xy"
}
],
"title" : "",
"firstname" : "",
"surname" : "f bar"
}
I've also tried this but it didn't work for me.
thank you for text data -
this is something you could play with:
db.kieron.aggregate([{
$unwind : "$bookings"
}, {
$match : {
"bookings.transactions" : {
$exists : true,
$not : {
$size : 0
}
}
}
}, {
$group : {
_id : "$agencyID",
count : {
$sum : {
$size : "$bookings.transactions"
}
}
}
}
])
as there is nested array we need to unwind it first, and then we can check size of inner array.
Happy reporting!

Using 'findAndModify' on mongodb within multiple nested array (complex)

I have the next document in a collection:
{
"_id" : ObjectId("546a7a0f44aee82db8469f6d"),
...
"valoresVariablesIterativas" : [
{
"asignaturaVO" : {
"_id" : ObjectId("546a389c44aee54fc83112e9")
},
"valoresEstaticos" : {
"IT_VAR3" : "",
"IT_VAR1" : "",
"IT_VAR2" : "asdasd"
},
"valoresPreestablecidos" : {
"IT_ASIGNATURA" : "Matemáticas",
"IT_NOTA_DEFINITIVA_ASIGNATURA" : ""
}
},
{
"asignaturaVO" : {
"_id" : ObjectId("546a3d8d44aee54fc83112fa")
},
"valoresEstaticos" : {
"IT_VAR3" : "",
"IT_VAR1" : "",
"IT_VAR2" : ""
},
"valoresPreestablecidos" : {
"IT_ASIGNATURA" : "Español",
"IT_NOTA_DEFINITIVA_ASIGNATURA" : ""
}
}
]
...
}
I want modify an element of the valoresEstaticos, I know the fields "_id", "asignaturaVO", and the key of the item valoresEstaticos that I want modify.
Which is the correct query for this?, I have this:
db.myCollection.findAndModify({
query:{"_id" : ObjectId("546a7a0f44aee82db8469f6d")},
update: {
{valoresVariablesIterativas.asignaturaVO._id: ObjectId("546a389c44aee54fc83112e9")},
{ $set: {}}
}
})
but I dont know how to build a query :(
Help me please, Thank you very much!
You can just use update.
db.myCollection.update(
{ "_id" : ObjectId("546a7a0f44aee82db8469f6d"), "valoresVariablesIterativas.asignaturaVO._id" : ObjectId("546a389c44aee54fc83112e9") },
{ "$set" : { "valoresVariablesIterativas.$.valoresEstaticos.IT_VAR3" : 99 } }
)
assuming you want to update key IT_VAR3. The key is the positional update operator $. The condition on the array in the query portion of the update is redundant for finding the document, but necessary to use the $ to update the correct array element.