I'm rethinking how I want to structure some data which is currently being stored in the Users Collection. Previously, my server would receive messages, find the user document with the right profile.website field, and push an item into the profile.siteMessages array:
{
"_id": "hr9ck5Fis5YuvqCqP",
"profile": {
"website": "localhost",
"siteMessages": [
{
"text": "sddsd",
"createdAt": 1482001227204
},
]
}
}
Id like to change the structure to look something like the following. Instead of storing all messages, of which multiple messages could come from the same user, in a top level array in profile, I would have a profile.siteVisitors field which contains a visitorId and then the array of messages:
{
"_id": "dgfsdfdfsdf",
"emails": [
{
"address": "[email protected]",
"verified": false
}
],
"profile": {
"website": "localhost",
"siteVisitors:" [
{
"visitorId": "74585242",
"messages": [
{
"text": "A string",
"createdAt": 1482001260853
},
{
"text": "Another string",
"createdAt": 1482001260854
}
]
},
{
"visitorId": "76672242",
"messages": [
{
"text": "A string",
"createdAt": 1482001260855
}
]
}
]
}
}
Keeping with the structure shown above, how would I query for and update the profile.siteVisitiors.messages array? Currently I query and update the Collection using something like the following:
Meteor.users.update(
{'profile.website': url},
{$push: {'profile.siteMessages': msgItem}},
function(err) {
if (err) {
console.log('whoops!' + err)
} else {
//success
}
});
How would I update the newly structured messages array? I would need to match a User documents profile.website field, match a visitorId in the profile.siteVisitors array, and then push a new element into the messages array, but I'm not sure how this would look as a MongoDB query.
EDIT I've hacked together the following which seems to work, but is very ugly. How can I improve this?
Meteor.users.update(
{"profile.website" : "localhost" , "profile.siteVisitors" : {$elemMatch: {"visitorId" : data.chirpVisitorId} } },
{$push: { "profile.siteVisitors.$.messages": {"text" : data.msg, "createdAt" : data.msg.createdAt} } },
function(err, res) {
if (err) {
console.log('failed to push ' + err)
} else {
console.log('success on new push ' + res)
if (res < 1) {
let item = {
"visitorId": data.chirpVisitorId,
"messages": [data.msg]
}
Meteor.users.update(
{"profile.website": "localhost"},
{$push: {'profile.siteVisitors': item}},
function(err, res) {
if (err) {
console.log(err)
} else {
console.log(res + " updated")
}
}
)
}
}
})