How to query for an object within an array in mongoose - javascript

I'm new to mongoose and I'm having trouble querying for specific objects within an array.
My data model looks like this:
{
"users": [
{
"_id": "61b0d6637e169ddebf72c18a",
"name": "Brian Test",
"email": "briantest#gmail.com",
"password": "xxx",
"accountType": "type1",
"__v": 0,
"title": "title1",
"about": "about1",
"education": [
{
"recordId": 1,
"institution": "institution1",
"title": "title1"
},
{
"recordId": 2,
"institution": "institution2",
"title": "title2"
},
{
"recordId": 3,
"institution": "institution3",
"title": "title3"
}
]
}
]
}
The query I need is to perform a crud on education records. For it I'll have the user ID and the education record ID.
I'm not sure how to nest the education record query within the user query.
I've tried something like this but It's not working.
let user = await User.findOne({_id: req.user.user.id})
let recordToUpdate = await user.education.findOne({recordId: req.body.recordId})
console.log(recordToUpdate)
I'll appreciate if you could give examples for reading, updating and deleting records aswell.
Thanks!

Related

update nested array data in mongodb and node js

I want to update status in corder data. i try many time but i cannot update that data. if you know how update that data ??
{
"_id": "63064232cf92b07e37090e0a",
"sname": "Bombay collection ",
"name": "Hussain Khan",
"costomer": [
{
"cname": "Basan",
"cphone": 9863521480,
"_id": "632eeff2a9b88eb59d0210f0",
"corder": [
{
"clothType": "Shirt",
"date": "2022-10-21",
"status": "false",
"_id": "635283363edde6a0e9e92dc0"
},
]
}
]
}
You can use $[<identifier>]. For example:
db.collection.update(
{},
{$set: {"costomer.$[elemA].corder.$[elemB].status": newStatus}},
{arrayFilters: [
{"elemA._id": costomerId},
{"elemB._id": corderId}
]}
)
See how it works on the playground example

Within an array, remove an item from an array within each object that item appears in

My mongodb document(table) 'Org_unit' looks like this:
{
"_id": ObjectId("0894f016e6e2e073c19e051")
"allowedusers": [
"admin",
"Fred",
"Bob",
"Layneh"
],
"name": "News management",
"divisions": [
{
"allowedusers": [
"admin",
"Larry",
"Bob",
"Harry",
"Fred"
],
"_id": ObjectId("60894f016e6e2e073c19e052"),
"name": "Finances",
"credentials": [
{
"_id": ObjectId("94f0944f016e6e2e2342cc"),
"name": "FNB - FA",
"userName": "example#email.com",
"password": "examplePassword!##"
}
]
},
{
"allowedusers": [
"admin",
"Larry",
"Bob",
"Harry",
"Fred"
],
"_id": ObjectId("60894f016e6e2e073c19e052"),
"name": "Development",
"credentials": [
{
"_id": ObjectId("94f0944f016e6e2e2342cc"),
"name": "FNB - DEV",
"userName": "example#email.com",
"password": "examplePassword!##"
}
]
}
],
"__v": 11
}
This is my fist post here, hello! Ok so I have been at this for a few days now and I just cant get this right.
What I am trying to do:
Within the "divisions" array, I want to remove "Fred" from the "allowedusers" array in each object "division" that he appears in.
What I have tried
I am still very new, about a week in.
I have tried many times, but the closest I have gotten was this:
Org_unit.updateMany({name: "News management"}, { $pull: {'divisions': {'allowedusers': "Fred"}}},{ multi: true })
^^ This deleted the entire division if he appeared in its "allowedusers" array
Any guidance with this is massively appreciated
Thank you in advance.
PS: (Since this is my first question posted, please let me know how I can improve my questions in the future!)
Demo - https://mongoplayground.net/p/kR_NmQNO52y
Use $[]
The all positional operator $[] indicates that the update operator should modify all elements in the specified array field.
db.collection.update({
name: "News management"
},
{
$pull: {
"divisions.$[].allowedusers": "Fred"
}
})

How to query two collections that have a "one-to-many" relationship in MongoDB?

We have two collections: "houses" and "events". Each document in the houses collection contains an "events" field with an array of id's that refer to events (a "one-to-many" relationship). The array can be empty.
"House" schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const HouseSchema = new Schema({
name: String,
district: String,
locality: String,
date: {
type: Date,
default: Date.now
},
events: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Event'
}]
});
module.exports = mongoose.model('House', HouseSchema);
"Event" schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const EventSchema = new Schema({
event: String,
details: String,
date: {
type: Date,
default: Date.now
},
house: {
type: mongoose.Schema.Types.ObjectId,
ref: 'House'
}
});
module.exports = mongoose.model('Event', EventSchema);
I need to query both "houses" and "events" and find those "houses" with referred "events" that meet all the criteria. I will give several options for queries.
Query with parameters only from "houses". Let's say there are two docs in the "houses" collection that satisfy the condition {"locality": "Facebook"}. The result should be like this:
[
{
"_id": "601bae8e26ed00591d571dbe",
"name": "Facebook testing department",
"district": "Los-Angeles",
"locality": "Facebook",
"events": [
{
"_id": "601bae8e26ed00591d571dbf",
"event": "Testing",
"details": "Testing software for production",
"date": "2020-07-31T21:00:00.000Z"
}
]
},
{
"_id": "601bae8e26ed00591d571dbc",
"name": "Facebook office",
"district": "Los-Angeles",
"locality": "Facebook",
"events": [
{
"_id": "601bae8e26ed00591d571dbd",
"event": "Conference",
"details": "Developers conference about 12345",
"date": "2020-07-31T21:00:00.000Z"
}
]
},
];
Query with parameters only for "events". Let's say there are two records in the "events" collection that satisfy the condition {"event": "Conference"}. The result is:
[
{
"_id": "601bae8e26ed00591d571dbc",
"name": "Facebook office",
"district": "Los-Angeles",
"locality": "Facebook",
"events": [
{
"_id": "601bae8e26ed00591d571dbd",
"event": "Conference",
"details": "Developers conference about 12345",
"date": "2020-07-31T21:00:00.000Z"
}
]
},
{
"_id": "601bae8e26ed00591d571dba",
"name": "Oxford",
"district": "London",
"locality": "Oxford",
"events": [
{
"_id": "601bae8e26ed00591d571dbb",
"event": "Conference",
"details": "About something",
"date": "2020-07-31T21:00:00.000Z"
}
]
},
];
Query with parameters for both "houses" and "events". If the criteria of our query is {"locality": "Facebook", "event": "Conference"}, then the result should be like this:
[
{
"_id": "601bae8e26ed00591d571dbc",
"name": "Facebook office",
"district": "Los-Angeles",
"locality": "Facebook",
"events": [
{
"_id": "601bae8e26ed00591d571dbd",
"event": "Conference",
"details": "Developers conference about 12345",
"date": "2020-07-31T21:00:00.000Z"
}
]
},
];
I have faced similar situations where it is necessary to make queries more complex than usual. But here we need to make a query - depending on the parameters - for one or two collections, and as a result, we should get "houses" with nested "events" that correspond the query parameters. I don't know MongoDB aggregation that well, would appreciate any help.
Declare your inputs
let locality = req.body.locality;
let event = req.body.event;
Initialize aggregation pipeline (replace HousesModel to your reql model name)
let p = HousesModel.aggregate();
Check condition for locality
if (locality && locality.trim()) p.match({ locality: locality });
$lookup with pipeline,
declare events array into let
match events condition in expression
check condition if events search is available then put condition
p.lookup({
from: "events", // replace your actual collection name if this is wrong
let: { events: "$events" },
pipeline: [
{
$match: {
$and: [
{ $expr: { $in: ["$_id", "$$events"] } },
(event && event.trim() ? { event: event } : {})
]
}
}
],
as: "events"
});
make sure events is not empty
p.match({ events: { $ne: [] } });
execute above pipeline
let result = await p.exec();
Playground
Combine above code in sequence and test.

How do I made a relation in two entities if one entity has arrays data

I have two tables name users and requests in MYSQL database here is json example of each sequelize model which I need to map to my models:
user:
{
"username": "",
"profileImage": "",
"deleted": false,
"active": false,
"id": 9,
"uuid": "9a6d5a15-8e11-42aa-ac56-0bec272c9287",
"firstName": "M",
"lastName": "Aslam",
"email": "hang#outlook.com",
"isGuest": false
}
and request
{
"id": 5,
"requestUUID": "ab966593-95e5-4fd8-b433-01b116e3edee",
"socialLinks": [
{
"url": "https://synavos.com",
"socialLinks": [
{
"platform": "facebook",
"handle": "https://www.facebook.com/synavos/"
},
{
"platform": "instagram",
"handle": "https://www.instagram.com/synavosbusiness/"
},
{
"platform": "youtube",
"handle": "https://www.youtube.com/channel/UCrZxxAV_OiRb9N3wIe3N94w"
}
]
},
{
"url": "https://www.confiz.com/",
"socialLinks": [
{
"platform": "facebook",
"handle": "http://www.facebook.com/ConfizCareers"
},
{
"platform": "youtube",
"handle": "https://www.youtube.com/channel/UCG64lwoDIbwtkZK8E_s140A"
}
]
}
]
}
while a user can have many requests while a request belongs to one user.
if the relation is one to mant (user can have many requests while a request belongs to one user) you can add to request a user_id field. then you can search all request of the user by SELECT * FROM requests where user_id = ?, [user.id], and if you want find the user of a specific request use SELECT ALL FROM users WHERE id = ?, [request.user_id]

Return array of data instead of Dictionary - Sequelize

I need post data like array, but I send it always like this:
{
"books": [
{
"id": 19,
"name": "Král Lávra",
"author": "Karel Havlíček Borovský",
"yearOfRelease": "1920",
"price": "120",
"SubjectId": 1,
"UserId": 2,
"SchoolId": 1
},
]
}
I want show result like this:
[
{
"id": 19,
"name": "Král Lávra",
"author": "Karel Havlíček Borovský",
"yearOfRelease": "1920",
"price": "120",
"SubjectId": 1,
"UserId": 2,
"SchoolId": 1
},
]
I use sequelize to connection between database MySQL. This is my code for findAll books:
let books = await ctx.db.Book.findAll({
where: {
UserId: id
},
})
Then I only post to
ctx.body= {
books
}
Thanks for your response.

Categories

Resources