I’m having an issue where I’m attempting to update my document and the change is not being reflected. I suspect MongoDB is finding that my value is somehow the same even though I’ve changed it
var message = user.messages;
//should be an empty array for right now, can be something like [{ from: 'erin', to: 'erin', content: 'test' }]
//in the future
if (!message[otherPerson]) message[otherPerson] = [];
await message[otherPerson].push(msg);
//where msg is a msg object
//pushes message into new index
//updates messages with new data
const test = await User.updateOne({ usertag: person }, {
$set: { messages: message }
});
console.log(await test);
I’ve tried multiple formats of updating such as
User.updateOne({ usertag: person }, {
messages
});
where the messages variable is called message in the earlier example or
User.updateOne({ usertag: person }, {
$set: { messages }
});
and nothing seems to work
I will also mention that this is some rather old code that used to work pretty well. Has something changed in how MongoDB handles updates or am I doing something wrong?
Could you share the original code? This way we can compare to your
you have tried.
What you are doing is such a basic operation that I do not see
Note that the document is not updated if you supply the same value that was already there.
And reading the messages from the original document, and then using js code to do
following by a $set that sets all the old messages with the new msg you pushed is slow and error prone. A $push directly in the messages is both faster and safer.
Hi! I’m so sorry this thread has been so frustrating for everyone, but I appreciate all your help nonetheless!!
I did actually take your suggestion and use $push instead
It worked immediately and I’m sure the O(n) is MUCH better than what I was trying
If I may, however, I still have one more problem.
And this is my fault, I suppose I should have followed a tutorial or something
But I’d like to know if there’s anyway I can improve my data structure for a better implementation of my code.
See, the way I have it is in the document I have this Messages object
and in that object I will be storing ALL the messages a user has received.
the way I want to grab the messages I want for the user is with the following code
I have otherPerson (always going to be someone else) and user (always going to be user)
const messages = await User.findOne({ usertag: user }).lean().messages;
const res = messages.filter(m => (m.to == user || m.to == otherPerson) && (m.from == user || m.from == otherPerson));
where messages will be ALL the messages the user has ever sent and res will be an array of the messages I want to grab
However, it seems like the time complexity will get MUCH worse as n increases, is there any better way that I could have written my code? I mean, there’s always a better way I suppose but I’d like some tips if anyone’s willing to share thanks!
Here, I would have done it the other way around. A user has greater control on the messages he sends compared to the messages he receives. So if Message is an object within the User, then I would store the message he sends.
I like the bucket pattern to store old messages (ex: 1 bucket per month per user) and embedded array for recent both sent and received messages. Most of the time a User is more interested in the recent messages he sent and received. You have all that in one document. From time to time, he needs to access old messages, but I am pretty sure most people can tolerate a slower history access compared to current affairs.
I also like to keep messages in both sender and receiver current and history. A sender might want to remove a message from its sent list while the receiver really wants to keep it, or the other way around.
Definitively recommended. The mongodb university gives good and free courses.