MongoDB: как получить доступ к родителю списка при использовании $ where - PullRequest
0 голосов
/ 17 мая 2011

Образец данных

{
  "Subject": "New thread"
  "Messages": [
    {
      "DateSent": "Mon, 16 May 2011 14:34:17 GMT -04:00",
    },
    {
      "DateSent": "Mon, 16 May 2011 14:59:57 GMT -04:00",
    }
  ],
  "Participants": [
    {
      "UserId": 2,
      "LastReadMessageIndex": 0,
    },
    {
      "UserId": 1,
      "LastReadMessageIndex": 1
    }
  ],
}

В ветке содержится список сообщений и список участников.Когда участник просматривает поток, LastReadMessageIndex обновляется до длины сообщений.

Я хочу получить количество потоков, где есть непрочитанные сообщения для данного участника.Я могу использовать операцию $ where в моем списке участников следующим образом:

db.MessageThreads.find( {Participants: {$elemMatch: { UserId: 2, $where: {this.LastReadMessageIndex) < this.**parent**.Messages.length}}} }).count();

Возможно ли получить доступ к родительскому объекту?

1 Ответ

1 голос
/ 17 мая 2011

Я думаю, что проблема здесь в том, что вы соединяете $elemMatch и $where.В контексте $where значением this должен быть сам документ.Однако, похоже, вы говорите, что this является поддокументом.

Вот пример кода, который делает то, что вы хотите:

unread = function () {
    for (var i in this.Participants) {
        if (this.Participants[i].UserId == 2 &&
            this.Participants[i].LastReadMessageIndex < this.Messages.length) {
                return true;
        }
    }
    return false;
}

db.MessageThreads.find(unread)

Единственная проблема здесь заключается в том, чтоЯ жестко запрограммировал от UserId до 2.Если вы планируете вызвать это из одного из драйверов клиента, вам нужно будет ввести 2 в нужное место.

Если это кажется немного «хакерским», то это так.Вы пытаетесь сравнить поддокументы в одном документе, и MongoDB не очень хорош в этом, и структура вашего документа не делает это простым.

Вы можете рассмотреть:

"Participants": {
  "2": { "LastReadMessageIndex": 0 },
  "1": { "LastReadMessageIndex": 1 }
}

Эти изменения не решат проблему полностью, но они значительно упростят запрос:

unread = function() { 
  return (this.Participants['2'].LastReadMessageIndex < 
    this.Messages.length);
}

Если это важный запрос, вы можете подумать о создании Map / Reduce для этого процесса.вместо этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...