Reputation: 656
I have a activityFeeds
collection where each document's primary key is the same _id as the user's _id it refer to.
I did a getTimeKey function that return a string according to a specific date
/*
** Return a string like 1_2015 for january 2015
** If timestamp is not defined, current date is used
*/
getTimeKey = function (timestamp)
{
var date = (timestamp === undefined ? new Date() : new Date(timestamp));
return date.getMonth().toString() + "_" + date.getYear().toString();
}
When I use it in JS to access an object propertiy, it works great :
myProperty = myObj[getTimeKey()]; // get the aray of activity for the current month
The problem is when I want to add an activity to my document / collection, getTimeKey() is interpreted as a string in the mongo query.
/*
** Add a new activity to a user activity feed
** Get the time key from the passed date
** Returns false if a required parameter is not defined
** If the user has already an activity feed started, then check if the time key exists
** If it exists, push it the new activity, else create it
** If the user do not already have an activity feed started, then create it
**
** PARAMETERS :
** uid -> user's activity feed to update
** type -> the type of activity, see below
** data -> some specific data, see below
** date -> (optionnal) the date of the event
**
** TYPES :
** "ntt" -> data: { tId: threadId }
** "reply" -> data: { tId: threadId, pId: postId }
** "mate" -> data: { mId: mateId }
*/
addNewActivityTo = function (uid, type, data, date)
{
if (uid && type && data && timeKey)
{
var feed = ActivityFeeds.findOne({_id: uid}, {fields: {getTimeKey(date): 1}});
if (feed)
{
if (feed[getTimeKey(date)])
{
ActivityFeeds.update({_id: uid}, {
$push: { getTimeKey(date): { type: type, data: data, date: date } }
}, {multi: false});
}
else
{
ActivityFeeds.update({_id: uid}, {
$set: { getTimeKey(date): [ { type: type, data: data, date: date } ] }
}, {multi: false});
}
}
else
{
ActivityFeeds.insert({
_id: uid,
getTimeKey(date): [ { type: type, data: data, date: date } ]
});
return { type: type, data: data, date: date };
}
}
devError("Couldn't add new activity to user, parameters are missing.");
return false;
}
What I want is to be able to create the wanted key in the query (for example, 7_2014 for september. of 2014) or to search for it. How can I make mongo understand that he must look for the return of getTimeKey() and not take it as a string ?
If I store getTimeKey() return like this : var timeKey = getTimeKey(date);
, and replace every getTimeKey(date) by timeKey, it can insert it in the database, but the property key will be "timeKey"
. As it currently is, it throw me a Meteor build error because of the unexpected parenthesis.
Has anyone already faced that problem ?
Upvotes: 0
Views: 2080
Reputation: 3155
Here's an example of how to build an activity feed with MongoDB: https://github.com/GetStream/mongodb-activity-feed
The Data Model The MongoDB activity feed project uses 5 different schemas:
Upvotes: 0
Reputation: 50416
JavaSript "stringifies" all content on the "key" side when used in "Object Notation". Therefore use the "Array notation" to dynamically set keys from code:
var query = {_id: uid},
projection = { "fields": {} };
projection["fields"][getTimeKey(date)] = 1;
var feed = ActivityFeeds.findOne(query, projection);
That makes the "projection" object in this case look like:
{ "fields": { "7_2014": 1 } }
Which is the sort of result you are after.
Upvotes: 1