Sequelize user.increment("somethings") do not update the value - javascript

when I try to increment something with sequelize it doesn't return me the updated value (incremented) and to get that I need to reuse findOne method.
Looking in the sequelize doc here in the increment section you can read this:
The updated instance will be returned by default in Postgres. However,
in other dialects, you will need to do a reload to get the new values.
Is ther any way to "fix" it without using this "workaround" ( recalling findOne )?
const user = await Tags.findOne({
where: { id: ID },
});
await user.increment("rank");
const user1 = await Tags.findOne({
where: { id: ID },
});

Related

Mongoose search by array entries ($in) behavior not aligned with MongoDB Atlas

I'm running a Node.js server, connecting to a MongoDB database with mongoose.
Inside my controller, I have several methods that make operations to the database. One of them is this one:
async findMultiple(req, res) {
const [baseSkillsArray] = Array(req.body);
try {
// if there is not baseSkillsArray, skip
if (!baseSkillsArray) {
return res.status(200).send([]);
}
// find all baseSkills using the ids in the baseSkillsArray
const allBaseSkills = await BaseSkill.find({
_id: { $in: [baseSkillsArray.baseSkillArray] } //
});
console.log('test ' + allBaseSkills);
res.status(200).send(allBaseSkills);
} catch (error) {
console.error(error.message);
res.status(500).send('Server error find BaseSkills');
}
}
However, this returns me nothing. I did some debugging and I found the reason is the find id $in the array. So I tried hard coding a value, like '2', for instance.
// find all baseSkills using the ids in the baseSkillsArray
const allBaseSkills = await BaseSkill.find({ _id: { $in: ['2'] } });
No success. So I went to MongoDB Atlas, where my DB is stored. I tried filtering using the same line of code in my collections.
{ _id: { $in: ['2'] } }
Surprisingly, it returns my document as I wanted!
The issue is that I need to make it work with mongoose. Any ideas? Is this a known bug?
There is nothing wrong with the query, nor a bug regarding $in.
In fact, what's wrong is the actual collection name. I manually created a collection in MongoDB Atlas, called "baseSkills". However, mongoose by default transforms your collection name into lowercase and adds an "s" if your collection's name is not in the plural.
So every time I started my server, I noticed that there was a new collection called "baseskills". I assumed it was a bug and deleted it. Only after making this post that I realized the collection was there again.
So I exported the documents to this collection and my query was working fine.
FYI, there is a way to enforce the collection's name in mongoose. When you declare you model, add a second parameter to the Schema function called "collection". Here is an example:
const BaseSkillSchema = new mongoose.Schema({
_id: {
type: String,
required: true
}, ...
}, { collection: 'baseSkills' })
That's it! Sorry for the mess and thank you for your help!
you want to query over mongo db object ids. So you should create a new ObjectId to do that.
import {Types} from 'mongoose';
{ _id: { $in: [new Types.Object("2")] } }
Or if you have 2 ids one generated and one custom created as id then you can query without creating a new object.
{ id: { $in: ['2'] } }

How do I get a virtual in mongoose, If a property is deselected

lets say I have post Model and schema contains UserId , Title, Desc and likes array which takes userId's as ref
when I make a query I get a virtual property like this to find out num of like of a post would have
schema.virtual("numLikes").get(function () {
return this.likes.length;
});
But the problem is when I run the findById() Method I dont want to get likes from database because likes array would contain large list of users
const post = await Post.findById(postId).select("-likes -shares");
so how do I get Likes count without fetching likes array ?
I believe this can be done using aggregation, by using the $size operators in a projection:
const aggregate = Post.aggregate([
{ $match: {_id: postId}},
{ $project: {
numberOfLikes: { $size: "$likes" }
}
}
]);
https://docs.mongodb.com/manual/reference/operator/aggregation/size/
https://mongoosejs.com/docs/api/aggregate.html#aggregate_Aggregate-project

Updating Multiple Records with varying conditions in a single query

With Typeorm + NestJS + Postgres is there a way to update multiple records with varying conditions and varying values in a single query. Normally I could do
await getConnection()
.createQueryBuilder()
.update(Entity)
.set({ columnName: "newValue" })
.where({ id: In(1,2,3,4,5,6) })
.execute();
and this will update all entries with the specified ID. But in the case of having the following data structure
const array = [{id: 1, value: 'New Value For Record 1'},..., {id: 1000, value: 'New Value For Record 1000'}]
I could use for loop to update each single entry as below:
array1.forEach(rec => {
usersRepo.update(
{ id: rec.id },
{
columnName: rec.value
}
);
})
but this does not seem to be efficient and won't give good performance. Is there a way to do achieve multiple update on varying conditions with query builder.
You can achieve that we two queries
Get all the rows you need, basically a find would be enough, like this.
after that map the results array to do your changes
Last thing to do is to use save method, from Typeorm docs:
save - Saves a given entity or array of entities. If the entity already exists in the database, then it's updated. If the entity does not exist in the database yet, it's inserted.
const array = await yourRepo.find()
const newArr = array.map(el=> ({...el, value: 'New Value For Record'+el.id})
await yourRepo.save(newArr)
Cheers.

Mongo update removing other keys in document

I am trying mongo update where one document key from a different collection is inserted into another collection.
CODE
// update user document with remove of otp and new state set.
updateOne = await db.collection(_collection).updateOne(
// search basis.
__docUpdateSearchBasis,
// updates.
__docUpdateBasis
)
RESULT
You need to make query like this:
updateOne = await db.collection(_collection).findOneAndUpdate(
//Condition
{
_id: req.user.id
},
//Update what you want
{
$set: {
key: value
}
});

How to query linked documents in mongodb

I'd like to know if there's a way to directly search within a linked collection.
I'm using Express with mongoosejs
I have the following situation.
I have 3 collections, deal, product and store and I have associated product and store with the deal collection.
const DealSchema = new Schema({
...
product: {
type: Schema.Types.ObjectId,
ref: 'product'
},
shop: {
type: Schema.Types.ObjectId,
ref: 'shop'
},
...
});
In my collection product, I have a field called upc.
I have a controller that handles deals creation, however before I create a deal, I want to check whether or not there's already a deal with the same UPC in this store if so I'll only update the confirmedBy field.
This is my controller
async create(req, res) {
const dealProps = req.body;
const product = await Products.findOne({ upc: dealProps.upc });
let deal;
if (product) {
deal = await Deals.findOne({ product: product._id });
if (deal.shop.toString() === dealProps.shop.toString()) {
const updatedDeal = await Deals.findOneAndUpdate({ product: product._id }, {
$push: {confirmedBy: dealProps.user }
});
res.send(updatedDeal);
}
} else {
deal = await (new Deals(dealProps)).save();
res.send(deal);
}
}
I've tried to search directly within the product collection like this:
const product = await Deals.findOne({'product.upc': dealProps.upc });
However it returns null.
Is there a way to search directly within a linked collection? Do I need to create an index for the upc field in the product collection?
If not, should I rethink my deals collection to add the upc and storeId to simplify the lookup?
Thank you for your help, much appreciated.

Categories