How can I upsert many fields in prisma ORM with one query?
I don't want to use upsert fields one by one. Can I upsert all of them with one query?
You can't do it right now in Prisma.
Most efficient way if you need to handle lots of data would probably be something like that:
prisma.$transaction([
prisma.posts.deleteMany({ where: { userId: 1 } }),
prisma.posts.createMany({
{ id: 1, title: 'first', userId: 1 },
{ id: 2, title: 'second', userId: 1 },
{ id: 3, title: 'third', userId: 1 },
}),
]);
So you delete existing records and then recreate them again inside of a transaction.
Depending on the database (and schema) you use, Prisma supports an optional boolean within a createMany call: skipDuplicates, see https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#createmany
Do not insert records with unique fields or ID fields that already exist. Only supported by databases that support ON CONFLICT DO NOTHING.
Related
I am trying to populate my user property which is an array of duplicate id's and a reference to the User Schema.
schema={
// Array of duplicate userId
user: [{
type: mongoose.Schema.Types.ObjectID,
ref:'Users'
}]
}
Can I populate only distinct id's using mongoose here?
Yes, you can by following method.
db.collection_name.ensureIndex( { user : 1 }, { unique:true, sparse:true } );
In Mongoose, I have two collections, with one referencing the other. Is it possible to have a find query that selects records based on a value in the other. An example of what I am try to get at (not actual schemas):
const CarModelSchema = new mongoose.Schema({
name: String,
brand: { type: mongoose.Schema.Types.ObjectId, ref: 'CarBrand' }
});
const CarBrandSchema = new mongoose.Schema({
name: String,
country: String
});
I then want to perform a query of the form, without needing to do two queries:
CarModelSchema.find({ 'brand.country': 'GER' });
So far I haven't been able to make this work, so I am wondering whether this can be done in Mongo or whether I am approaching it wrong?
Yes it is possible.
I realize you don't have models for your schemas so add them like this:
const CarModel = mongoose.model('CarModel', CarModelSchema);
const CarBrand = mongoose.model('CarBrand', CarBrandSchema);
Also brands should be defined like this:
brand: [{ type: mongoose.Schema.Types.ObjectId, ref: 'CarBrand' }] //added the brackets
You can then run a find query to filter by country by doing the following:
CarModel.
find(...).
populate({
path: 'brand',
match: { country: { $eq: 'GER' }},
// You can even select the field you want using select like below,
select: 'name -_id',
//Even limit the amount of documents returned in the array
options: { limit: 5 }
}).
exec();
And that should do it, as long as the ObjectIds saved in brands array in the CarModel collection are valid or exist.
Using match in your population will do the work.
CarModel.find()
.populate({
path: 'brand',
model: CarBrandModel,
match: { country: { $eq: 'GER' }},
})
.exec()
Keep in mind you have to define CarModel and CarBrandModel like this:
const CarModel = mongoose.model('CarModel', CarModelSchema)
const CarBrandModel = mongoose.model('CarBrandModel', CarBrandSchema)
Yes, you are doing it wrong.
In CarModelSchema.brand there is not string saved, there is ObjectId saved, therefore you have to find that ObjectId (the reference).
You can do it manually - first finding the CarBrandSchema.find({ 'country': 'GER' }); and then use its ObjectId (=_id), or you can use https://mongoosejs.com/docs/populate.html to populate your CarModel with the CarBrand object.
I know that this question might be beginner level but I haven't find anything yet.
I would like to update an array of objects with mongoose. I am interested in updating one object from the users array according to the index.
Usually one user is getting changed at a time.
Here is my schema:
_id: Schema.Types.ObjectId,
name: { type: String, required: true },
gm: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
users: [],
I want to update an object in the users array which is like this:
{
id:"5bcb7c7ff9c5c01b9482d244",
gm:"5bcb7c7ff9c5c01b9482d246",
name:"room 1"
users: [
{
id:"5bcb7c7ff9c5c01b9482d243",
stats:{
power:10,
mobility: 5,
vitality: 20
},
bag:{itemSlot1: "Knife",itemSlot2:"Sword" }
},
{
id:"5bcb7c7ff9c5c01b9482d241",
stats:{
power:10,
mobility: 5,
vitality: 20
},
bag:{itemSlot1: "Knife",itemSlot2:"Sword" }
]
}
I want to perform a patch or a post request to update one user each time from the user array. i am getting the id of the user from req.body to match it with my db.
My request is like this:
I would like to update based on a request like this:
data = {
stats={
power:"10",
vitality:"20"
}
}
Thanks in advance,
Cheers
You can do an update like this:
YourSchema.update({
'users.id': '5bcb7c7ff9c5c01b9482d243'
}, {
$set: {
'users.$.stats': data.stats
}
})
Which would update the first user with id 5bcb7c7ff9c5c01b9482d243 power stats to 20
This is using the update with the $ positional operator to update the element in the array.
Just have it set up in your post/patch request.
My models:
Recipe (id, name)
Ingredient (id, name)
Recipe_Ingredient (recipeId, ingredientId, quantity)
My associations:
Recipe.belongsToMany(Ingredient, { through: Recipe_Ingredient })
Ingredient.belongsToMany(Recipe, { through: Recipe_Ingredient })
My problem:
How can I create a Recipe with some Ingredients and the quantities attached to them?
I tried:
Recipe.create({
name: 'Pizza',
ingredients:[
{
name: 'mozarella',
recipe_ingredients: {
quantity: 5
}
}
]
}, {
include:[Ingredient]
})
Records are created for Recipe, Ingredient and the Recipe_Ingredient. The only problem is that the value of the quantity is not collected from the data source.
It was not possible to do this in the past, but in October 23, 2018 this was fixed in sequelize PR #10050.
As of today (2018-10-24) the fix is not released yet, but as soon as v5.0.0-beta14 comes out, you'll be able to do the following:
Recipe.create({
name: 'Pizza',
ingredients: [
{
name: 'mozarella',
recipe_ingredient: {
quantity: 5
}
}
]
}, {
include: Ingredient
})
Also, note that the correct usage is recipe_ingredient: in the singular form, not in the plural form as you tried in your question. This makes sense, because for a given Ingredient, associated with a given Recipe, there is only one Recipe_Ingredient involved, always.
If you do not want to wait for v5.0.0-beta14 (although it will probably be released very soon), you can install it directly from github's master branch as follows:
npm install --save https://github.com/sequelize/sequelize/tarball/master
A solution I found, inspired by answers of pedro around here (How do I ORM additional columns on a join table in sequelize?) and there is given by a change of perspective.
receipe (name:string)
ingredient (quantity:int)
type (name: string)
receipe.hasMany(ingredient, {as:'ingredients'} )
ingredient.belongsTo(type)
and then I can consume data like this:
receipe.create({
name: 'Pizza',
ingredients:[
{
quantity: 5,
type: {
name: 'ingredient 1'
}
}, {
quantity: 6,
type: {
name: 'ingredient 2'
}
} {
quantity: 5,
type_id: 1
}]
}, {
include:[{
model; ingredient,
as: 'ingredients',
include:[{
model: type
}]
}]
})
It has some drawbacks but it is good enough for me.
One problem can be that if you add two items of the same new type, you will get a unique key violation (as types are unique and sequelize will not try to search if the type exists before trying to create it).
Another problem is that if you specify just the type_id in the data, it will not actually return the type refereed by that in the result.
I am currently using StrongLoop as my API backend server and Mongodb as data storage engine.
Let's say there is a collection called article. It has two fields title, and content. And there are two frontend pages to display a list of articles and view a single article.
Obviously the data list page only need title field and the view page need both. Currently the GET method of StrongLoop API return all fields including content. It cost extra traffic. Is there any way that can just return specific field?
Mongodb support projection in find() method for this. How can I do the same thing by StrongLoop?
Have you taken a look at the filters offered. http://docs.strongloop.com/display/LB/Querying+models
Query for NodeAPI:
server.models.Student.findOne({where: {RFID: id},fields: {id: true,schoolId: true,classId: true}}, function (err, data) {
if (err)
callback(err);
else {
callback();
}
})
Query for RestAPI :
$http.get('http://localhost:3000/api/services?filter[fields][id]=true&filter[fields][make]=true&filter[fields][model]=true')
.then(function (response) {
}, function (error) {
});
You can use fields projections,
Sample Record:
{ name: 'Something', title: 'mr', description: 'some desc', patient: { name: 'Asvf', age: 20, address: { street: 1 }}}
First Level Projection:
model.find({ fields: { name: 1, description: 1, title: 0 } })
and I think Strong loop is not yet supporting for second-level object filter, does anyone know how to filter second-level object properties or is yet to implement?.
Second Level Projection: (Need help here)
Ex: 2
model.find({ fields: { name: 1, 'patient.name': 1, 'patient.age': 1, 'patient.address': 0 } })
// Which results { name } only