MongoDB -check if nested array record doesn't exist - mongodb

I have a document which looks like this:
"id":X,
"name": "X",
"email": "X",
"shows": ["id":X, ,"name":X,"season":X,"ep_id":X, "active" : true/false]
Inside shows can be many records with unique ID.
Given a show id,how can i check if active field is true or not for this record?
I want to do some action if the value of the field is false.
I've tried this but it gives me the full document.
userM.find({id: userID, 'shows.id': showID,'shows.active':true})
Thanks
Edit:
I managed to find a way using forEach manipulation on the query results.

Try This:
db.userM.find(
{ shows: { $elemMatch: { "id": "X", "active":true } } }
)

Related

Index and sort on nested variable field MongoDB

I have a document that looks like this :
{
"_id": "chatID"
"presence": {
"userID1": 1647627240464,
"userID2": 1647227540464
},
}
I need to query for each userID the chats where he is present and order by the timestamp in the presence map.
I am aware that this is probably not the best way to do, before i had 1 element per user meaning duplicating the chatIDs, but it's a pain to update them all because it would look like :
{
"_id": "userID1chatID",
"at": 1647627240464,
"ids": "30EYwO01_Nyq7dMqe_O3vfL3AH",
"members": ["userID1", "userID2", "userID3"],
"owner": "userID1",
"present": true,
"uid": "chatID",
"url": "databaseURL"
}
This would allow me to find the chats where userID1 is present: true and order by at DESCENDING.
The problem with this is that i need to update the at attribute for all the documents (one per user) for this same chat room.
How can i do this same query while maintaining a single document with present as a map ?
Problem : the index would be on a variable : userID1, userID2, etc...
like : present.userID1 and seems to not be convenient for use when userID1 can be removed from the present map if the user leaves the chat.
Please let me know if this is unclear, thanks in advance.

MongoDB v5.0.5 reference existing field in updateMany()

First time using MongoDB and I'm having an issue that I would appreciate some help with please.
Let's say I have a collection called "students" with documents in the collection structured as followed:
{
"_id": ObjectId("12345"),
"Name": "Joe Bloggs",
"Class_Grade": "b"
"Homework_Grade": "c",
}
I want to create an embedded document called "Grades" that contains the class and homework grade fields and applies this to every document in the collection to end up with:
{
"_id": ObjectId("12345"),
"Name": "Joe Bloggs",
"Class_Grade": "b"
"Homework_Grade": "c",
"Grades": {
"Class_Grade": "b",
"Homework_Grade": "c",
}
}
I have been trying to achieve this using updateMany() in MongoShell:
db.students.updateMany({}, {$set: {Grades: {"Class_Grade": $Class_Grade, "Homework_Grade": $Homework_grade"}}})
However, in doing so, I receive Reference Error: $Class_Grade is not defined. I have tried amending the reference to $students.Class_Grade and receive the same error.
Your advice would be greatly appreciated
There are a few mistakes in your query,
if you want to use the internal existing field's value, you need to use an update with aggregation pipeline starting from MongoDB 4.2, you need to wrap the update part in attay bracket [], as i added query.
use quotation in field name that you want to use from internal field ex: "$Class_Grade"
you have used field $Homework_grade, and in your documents it is G is capital in Grade so try to use exact field name $Homework_Grade
db.students.updateMany({},
[
{
$set: {
Grades: {
"Class_Grade": "$Class_Grade",
"Homework_Grade": "$Homework_Grade"
}
}
}
])
Playground

MERN stack, Mongodb updating all embedded document arrays with this value if they have a certain value

I am trying to updateMany() documents which are an array of documents, if they have a certain value. I am still learning mongodb and I know how to update all documents if they have this value with my new value. The problem I think I am having is that they are an array of documents so I need to go into each document find the field called courses go inside of it and find the document called name and then update it the value of name and I have been trying, but no luck. Also In the request I update the first collection no problem its when I get into the next collection where it does nothing like I already mentioned.
request.body.code = request.sanitize(request.body.code);
request.body.name = request.sanitize(request.body.name);
request.body.courses.forEach(course => {
course.code = request.sanitize(course.code);
course.name = request.sanitize(course.name);
});
let newValues = { $set: {"code": request.body.code, "name":request.body.name } };
result = await mongoClient.db(DB_NAME).collection("all_courses").updateOne(selector, newValues);
// Okay now try to update other collection of array documents which isnt working yet
selector = { "code": "PROG2700"};
newValues = { $set: {"code": request.body.code, "name": request.body.name } };
console.log("this is new values");
console.log(request.body.courses);
result = await mongoClient.db(DB_NAME).collection("technologies").updateMany(selector,newValues);
That is in my server doing the mongodb work and trying to update the documents.
let sendString:Object = {
"id": my,
"code": edit_Course?.code,
"name": state_category_name,
"courses":
[
{
"code": edit_Course?.code,
"name": state_category_name
}
]
}
That is what I am sending to the server as the request.body
{
"_id": "5fdaa52060689aa159e4122e",
"name": "Webpack",
"description": "Webpack is great",
"difficulty": 2,
"courses": [
{
"code": "PROG2700",
"name": "Client Side Programming"
},
{
"code": "PROG3017",
"name": "Full Stack Programming"
}
]
}
That is what the mongodb structure of each document looks like in the technologies collection that I am having trouble updating. Its the name field I need to update in every document under courses. Could anyone give me a helping hand, many thanks!
Your selector filter doesn't work for the technologies class because the matching code field is part of an array named courses. To account for this, the filter should look something like this:
{ "courses.code": "PROG2700" }
This is an example of querying a field in a document embedded in an array.
The next step is to update the right document in the array. This can be done in MongoDB using the positional operator $. The update document would look like this:
{ $set: { "courses.$.code": request.body.code, "courses.$.name": request.body.name }}
In this update document, the positional operator tells MongoDB to update the code and name fields of the first document in the courses array with a code of PROG2700.
Put together, the update might look like this:
filter = { "courses.code": "PROG2700" };
update = { $set: { "courses.$.code": request.body.code, "courses.$.name": request.body.name }};
result = await mongoClient.db(DB_NAME).collection("technologies").updateMany(filter,update);

How to make a cloudant query to find documents which two fields are equal

I need to get all documents whose e.g. "_id" field equal to another document field, e.g. "appId"
{
"_id": "xxxx-xxxx-xxxx-xxxx",
"_rev": "xxxx-xxxx-xxxx-xxxx",
"header": {
"appId": "xxxx-xxxx-xxxx-xxxx"
So what would be the query?
"selector": {
"_id": {
"$eq": header.appId
}
},
You can't do "sub queries" with Mango.
From what I see, you're trying to get all the documents listed by appId.
This could be done by using a view.
Your map function would be the following:
if(doc.header && doc.header.appId){
emit(doc.doc.header.appId,{_id: doc.header.appId});
}
The result would be a list of documents mapped by doc.header.appId.
If you query the view with ?include_docs=true, the documents would be joined to the response since we're doing a ManyToJoin join.

Mongodb: Update a field with data from a sub-sub field?

I'm trying to update a field in a collection with data from the same collection, but from a sub-sub field in it, and either can't get the syntax right, or I'm just doing it wrong.
I've spent quite some time now digging around here, but can't seem to get anywhere.
Here's the example structure of the users collection:
{
"_id": "12345qwerty",
"services": {
"oauth": {
"CharacterID": 12345678,
"CharacterName": "Official Username",
},
},
"name": "what I want to change",
"username": "OfficialUsername"
}
What I'm trying to do would be pretty trivial with SQL, ie: update all the display names to match a trusted source...
update users
set name = services.oauth.CharacterName;
...but I'm having trouble getting in MongoDB, and I have a feeling im doing it wrong.
Here's what i have so far, but it doesn't work as expected.
db.users.find().snapshot().forEach(
function (elem) {
db.users.update(
{ _id: elem._id },
{ $set: { name: elem.services.oauth.CharacterName } }
);
}
);
I can set the name to be anything at the base level, but can't set it to be something from the sublevel, as it doesn't recognise the sub-fields.
Any help would be greatly appreciated!
db.users.update({"services.oauth.CharacterName": {$exists: true}},{$set: {"name": "services.oauth.CharacterName"}},{multi:true})
I am setting name at the root of your document to be equal to the value in services.oauth.CharacterName in the sub sub document. multi = true will update multiple document, I am only updating documents that have the services.oauth.CharacterName value.