couchdb : implement joins and views - couchdb

I need to get below Result by joining Person and Department using CouchDB views and joins. How can this be achieved?
Person: {
name: 'Parnika',
city: 'Delhi',
dept: 'DevOps'
}
Department: {
name: 'DevOps',
city: 'Delhi'
}
Result: {
Person: {
name: 'Parnika'
city: 'Delhi',
Department: {
name: 'DevOps',
city: 'Delhi'
}
}
}

Instead of starting with "how do I do a join" (no relational joins as such in couchdb), start with what you want to achieve. For example, perhaps what you are trying to do is to map people to departments.
Look to denormalise your data so that each document contains all the data you expect from a row in a relational join:
Person: {
name: 'Parnika'
city: 'Delhi',
Department: {
name: 'DevOps',
city: 'Delhi'
}
}
Now you can create a view that maps Department.name to Person.name, something like
function(doc) {
if (doc && doc.name && doc.Department && doc.Department.name) {
emit(doc.Department.name, doc.name);
}
}
This view will let you find people grouped by department.

Related

How to query an attribute from an object inside of an array with Mongoose

I am trying to filter a list of 'professionals' using model.find() from Mongoose. The query I have works normally in MongoDB Compass but with Mongoose it does nothing.
The model goes like this:
{
name: string,
email: string,
password: string,
phoneNumber: number,
city: string,
myDescription: string,
specialty: [
{ name: string, certificate: string, isCertified: boolean }
],
image: { profile: string, jobs: [strings] },
availability: Boolean
}
The query in MongoDB Compass is { specialties: { $elemMatch: { name: 'Soldador General', isCertified: true } } } and it returns the list of 'professionals' as expected. When I use it in Mongoose it returns the entire list, so no filter.
Going through the documentation of Mongoose there is a method Query.elemMatch() but the problem is that the filter is dynamic, I want the users to filter by city, specialty or both, and also I might add some filters in the future. For now the queries look something like:
{ specialties: { $elemMatch: { name: 'Soldador General', isCertified: true } } }
{ city: 'Barranquilla' }
{ city: 'Barranquilla', 'specialties': { $elemMatch: { name: 'Soldador General', isCertified: true } } }
And so I don't see how to do this dynamically with Query.elemMatch(). BTW I retrieve the object using React useSearchParams and send the request via NodeJS.
Any help or guidance is highly appreciated!

Many to many relations prisma

I'm new to backend and stuff.
I have two models: Product and City. City can have many products and product can have many cities, so I created another table ProductsOnCities:
model City {
id Int #id #default(autoincrement())
name String
pickupPoints PickupPoint[]
products ProductsOnCities[]
}
model Product {
id Int #id #default(autoincrement())
title String
price Int
cities ProductsOnCities[]
}
model ProductsOnCities {
city City #relation(fields: [cityId], references: [id])
cityId Int
product Product #relation(fields: [productId], references: [id])
productId Int
##id([cityId, productId])
}
How can I insert data now? For example, I want to create city with 4 products (which is already existing in my database), do I really need to create 4 objects there as it shown in prisma docs? Below is an example from the documentation.
const assignCategories = await prisma.post.create({
data: {
title: 'How to be Bob',
categories: {
create: [
{
assignedBy: 'Bob',
assignedAt: new Date(),
category: {
connect: {
id: 9,
},
},
},
{
assignedBy: 'Bob',
assignedAt: new Date(),
category: {
connect: {
id: 22,
},
},
},
],
},
},
})
That's what I did:
const assignCategories = await prisma.city.create({
data: {
name: 'Toronto',
products: {
create: [
{
product: {
connect: {
id: 1
},
},
},
{
product: {
connect: {
id: 15
},
},
},
{
product: {
connect: {
id: 11
},
},
},
{
product: {
connect: {
id: 18
},
},
},
],
},
},
})
It's working good but is there any way to do it more succinctly? Do I really need to pass a new "big" object for each product i'm adding? I tried to pass the array of product id's to connect but it doesn't work.
Yes you would need to pass it this way as you're using explicit many-to-many relations.
You can convert your schema to implicit many-to-many relations and that would make the create/connect syntax easier.

Require a mongodb db model deign. Whether to choose Refs or Embeded doc

I'm designing a backend for a Talent hunt application. Initially I designed the DB using refs. Like I followed the primary key forign key using refs to join my collections. But as the collection requirement increases it's being hard to join all the collections. Then I come across the one to many collections. So I'm thinking to get a suggestion from experts. Let me tell the requirements.
I have the following collections initially.
User.js
{
_id: "5ecfdc903165f709b49a4a14",
name: "Lijo",
email: "lijo#gmail.com"
}
then I have a category table for serving the categories
Category.js
{
_id: 5ecfdc903165f709b49a5a18,
title: "Acting",
code: "ACT"
}
If one user adds his talents to profile. I used one another collection for storing. Rmember the user can save multilple talents. So i created,
UserTalents.js
{
_id: "5ecfdc903165f709b49a6c87",
categoryId: "5ecfdc903165f709b49a5a18",
userId: "5ecfdc903165f709b49a4a14",
level: "beginner"
}
For each catgeory need to upload atleast one media along with description Soagain I created a new collection for that.
Media.js
{
_id: "5ecfdc903165f709b49a8a14",
talentId: "5ecfdc903165f709b49a6c87",
userId: "5ecfdc903165f709b49a4a14"
media: "5ecfdc903165f709b49a4a14_1.jpg"
}
And I need to have these users connected. For that craeted.
Friends.js
{
_id: "5ecfdc903165f709b49a8a18",
sender: "5ecfdc903165f709b49a4a14",
receiver: "5ecfdc903165f709b49a4a15"
status: "accepted"
}
Is this good to continue??? Expecting a huge amount of users. Or can I follow like:
User.js
{
_id: "5ecfdc903165f709b49a4a14",
name: "Lijo",
email: "lijo#gmail.com",
talents: [
{
_id: "5ecfdc903165f709b49a5a18", // _id from Category
title: "Acting",
code: "ACT",
level: "beginner",
media: "5ecfdc903165f709b49a4a14_1.jpg"
}
],
friends: [
{
_id: "5ecfdc903165f709b49a4a15",
name: "Test",
status: "approved"
}
]
}
I I follow this, then how do I update the name fileds in talents and friends array either one of its original name is changed?
Which is better approach?

MongoDB - Update/Insert the Array of object

I've one collection i.e 'comments', Which contain two fields. Like below -
Comments -
{
_id: 'unique_string',
dataVar: [{
name: {
type: string
},
value: {
type: string
}
}]
}
You can assume the collection data is like below -
[
_id: 'xxxxxx',
user: 'robin',
dataVar: [{
name: 'abc',
value: 123
}, {
name: 'bcd',
value: 12345
}]
]
Now the problem is - (I'm using mongoose in nodeJS application)
- How to update and insert the data in 'dataVar' ?
- If data is no available then new document should be created.
Case 1.
If user send the post data like
{
_id: 'xxxxxx',
user: 'robin',
dataVar: [{name: 'abc', value: 12345}]
}
then after performing query, the above document (whose _id is 'xxxxxx') should be update like below -
{
_id: 'xxxxxx',
user: 'robin',
dataVar: [
{name: 'abc', value: 12345},
{name: 'bcd', value: 12345}
]
}
Case 2.
If data is not present then new document should be created.
To update record in mongodb, you can use like
comments.findOneAndUpdate({ _id: 'xxxxxx' }, { $push: { dataVar: {$each: [{name: 'abc', value: 123}, {name: 'def', value: 456}] } } })
You can use {upsert: true} option for creating field in collection if not exist.
For updating record, you have to use sub-schema inside your main schema. So that _id field is created in every object of array. So you can uniquely identify object to update inside array.
comments.findOneAndUpdate({ "dataVar._id": 'xxxxxx' }, { $set: { name: 'xyz', value: 789 } })
In this way, you can update object, which is inside array.
If you don't want to use _id, you have at-least one field which contains unique values. So that you can findOneAndUpdate that specific object inside array.

How to include documents as subdocuments in MongoDB?

I have a basic user collection that consists of document like so:
{
user: 3949fj9fn9rjhfne93,
name: "Jerry",
country: 'au',
friends: ['20fn39r4hf93', 'g9en3irhr934', '4i5henifuw92']
}
Each of those friends also has a document the same, along with there being a large collection of countries that can be queried via the country code.
{
code: 'AU',
name: 'Australia'
}, {
code: 'NZ',
name: 'New Zealand'
}
My question is, how would I include the full document for each of those array items within the result, like so:
{
user: 3949fj9fn9rjhfne93,
name: "Jerry",
country: {
code: 'AU',
name: 'Australia'
},
friends: [{
user: 20fn39r4hf93,
name: "Bob",
friends: ['2049429fr', 'djwij393i4']
}, {
user: g9en3irhr934,
name: "Foo",
friends: []
}, {
user: 4i5henifuw92,
name: "Bar",
friends: ['2049429fr']
}]
}
I am using Mongoose in my application, and I understand that this could be done by using a simple for loop and pushing the results to the user object and then returning it in node with res.json(user), although what if the user had hundreds (or even thousands) of friends? The request would be huge. I also need to do this in multiple places within my API.
Is there a more efficient way to achieve this?

Resources