2015-08-24 3 views
0

У меня есть коллекция activityFeeds, где первичный ключ каждого документа тот же _id, что и пользовательский _id, на который ссылается.Обработка фида активности пользователя с помощью mongoDB

я функцию getTimeKey, которые возвращают строку в соответствии с определенной датой

/* 
** 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(); 
} 

Когда я использую его в JS, чтобы получить доступ к объекту propertiy, он прекрасно работает:

myProperty = myObj[getTimeKey()]; // get the aray of activity for the current month 

Проблема когда я хочу добавить активность к моему документу/коллекции, getTimeKey() интерпретируется как строка в запросе mongo.

/* 
** 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; 
} 

То, что я хочу, чтобы иметь возможность создать разыскиваемый ключ в запросе (например, 7_2014 на сентябрь. 2014) или искать его. Как я могу заставить монго понять, что он должен искать возвращение getTimeKey() и не воспринимать его как строку?

Если хранить getTimeKey() возвращает так: var timeKey = getTimeKey(date);, и заменить все getTimeKey (дата) по timeKey, он может вставить его в базу данных, но основное свойство будет "timeKey". Как и в настоящее время, он бросает мне ошибку сборки Meteor из-за неожиданной скобки.

Неужели кто-нибудь уже столкнулся с этой проблемой?

ответ

1

JavaSript «строит» все содержимое на стороне «ключа» при использовании в «Обозначении объекта». Поэтому использовать «массив обозначения» динамически устанавливать ключи от кода:

var query = {_id: uid}, 
    projection = { "fields": {} }; 

projection["fields"][getTimeKey(date)] = 1; 

var feed = ActivityFeeds.findOne(query, projection); 

Это делает «проекция» объект в этом случае выглядит следующим образом:

{ "fields": { "7_2014": 1 } } 

Который является своего рода результат вы после ,

+0

Отлично работает! Это было так просто, что я даже не мог думать об этом. Спасибо вам, обновление придет вовремя :) –

+1

@DavidPanart Еще одна пара глаз на проблему. Это часто бывает полезно для stackoverflow. –

Смежные вопросы