Монго запрашивать разные атрибуты в разных строках - PullRequest
1 голос
/ 22 февраля 2012

У меня есть коллекция монго с полями визит_идентификатор, идентификатор_пользователя, дата, действие 1, действие 2

example:
1 u100 2012-01-01 phone-call -
2 u100 2012-01-02 - computer-check

Могу ли я получить в mongodb пользователя, который сделал телефонный звонок и проверку компьютера независимо от времени? (в основном это AND в разных строках)

Ответы [ 3 ]

1 голос
/ 23 февраля 2012

Вы не сможете сделать это с помощью одного запроса - если это то, что вы часто делаете в своем приложении, я бы не рекомендовал карту / уменьшить - я бы порекомендовал сделать запрос в mongodb, используя оператор $ или, а затем обрабатывает его на клиенте, чтобы получить уникальный набор идентификаторов пользователя.

Например:

db.users.find({$or:[{"action 1":"phone-call"}, {"action 2":"computer-check"}]})

В будущем вы должны сохранить свои данные в другом формате, подобном тому, который был предложен Эндрю выше.

1 голос
/ 22 февраля 2012

Я думаю, что это невозможно без работы с картой / уменьшением.

Я вижу, это можно сделать следующим образом:

1. Сначала вам нужно запустить карту / уменьшить, чтобы получить такие результаты, как это:

{
 _id : "u100",
 value: {
   actions: [
       "phone-call",
       "computer-check",
       "etc..."
  ]
 }
}

2. Затем вы можете запросить выше m / r результат через elemMatch

0 голосов
/ 23 февраля 2012

Для вашего запроса можно использовать MongoDB group метод , сравнимый с оператором SQL group by.

Я не проверял это, но ваш запрос мог выглядеть примерно так:

var results = db.coll.group({
    key: { user_id: true },
    cond: { $or: [ { action1: "phone-call" }, { action2: "computer-check" } ] },
    initial: { actionFlags: 0 },
    reduce: function(obj, prev) {
        if(obj.action1 == "phone-call") { prev.actionFlags |= 1; }
        if(obj.action2 == "computer-check") { prev.actionFlags |= 2; }
    },
    finalize: function(doc) {
        if(doc.actionFlags == 3) { return doc; }
        return null;
    }
});

Опять же, я не проверял это, это основано на моем чтении документации. Вы группируете по user_id (декларация key). Строки, которые вы хотите пропустить, имеют либо action1 == "phone-call", либо action2 == "computer-check" (объявление cond). Начальное состояние, когда вы начинаете проверку определенного user_id, равно 0 (initial). Для каждой строки вы проверяете, если action1 == "phone-call" и устанавливаете его флаг, и проверяете action2 == "computer-check" и устанавливаете его флаг (функция reduce). После того, как вы отметили типы строк, убедитесь, что установлены оба флага. Если это так, сохраните объект, в противном случае удалите его (функция finalize).

Эта последняя часть - единственная, в которой я не уверен, поскольку в документации явно не указано, что вы можете выбивать записи в функции finalize. Возможно, мне понадобится больше времени, чтобы настроить некоторые тестовые данные, чтобы увидеть, работает ли приведенный выше пример.

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