MongoDB сгруппировать несколько раз в два раза, прежде чем уменьшить - PullRequest
1 голос
/ 18 марта 2011

У меня есть коллекция событий = [timestamp, accountId, deviceId, rfid ...]

-rfids обнуляется, но все остальное не обнуляется - rfid сообщает через deviceId

Мне нужно найти состояние каждого RFID в моей системе.На первый взгляд это кажется тривиальным, если мы сопоставляем {accountId, deviceId, rfid}, однако состояние rfids также зависит от сообщающих событий deviceIds.Когда устройство сообщает, оно устанавливает значение rfid равным нулю (например, устройство может выключаться и выключаться).Как бы я решил определить одну функцию отображения на основе {accountId, deviceId, rfid}, а затем объединить коллекцию карт со всей сопоставленной коллекцией {accountId, deviceId, null}?

прямо сейчас я использую linqчтобы получить желаемый набор данных следующим образом:

events.GroupBy(new{deviceId, accountId}).Select( x=>new{
  Key= x.Key
  Value = x.GroupBy(y=>new{y.accountId, y.rfid}).Union(x.Where(z=>z.rfid== null))).ToList()
});

Ответы [ 2 ]

1 голос
/ 19 марта 2011

В наборе данных должны быть сделаны два прохода карты / уменьшения 1) map {acctid, deviceId, rfid} => уменьшить до массива [события] 2) сопоставить результаты (1) {acctId, deviceId} => приведения к массиву зафиксированных RFID на основе statusCode

Важно помнить, что параметр значения функции emit (2-й параметр) должен иметь ту же структуру, что и набор результатов. Это потому, что уменьшение выполняется итеративно! это было болезненной точкой при создании массива исходных событий.

0 голосов
/ 18 марта 2011

Ну, не уверен, что это проблема типа "не вижу дерево из леса". Если вы группируете по {deviceId, accountId}, у вас уже есть как нулевые, так и ненулевые RFID в группе. Если я вас правильно понял, {deviceId, accountId} имеет уникальный rfid, если это так, просто извлеките первый ненулевой rfid из группы и всех ее элементов в качестве значений:

var p = from e in events 
    group e by new { e.accountId, e.deviceId } into g
    let rfid = g.First(ge => ge.rfid != null).rfid
    select new { 
        Key = new { g.Key.accountId, g.Key.deviceId, rfid }, 
        Values = g.ToList() 
    };

Если, с другой стороны, на вашем устройстве, в комбинированном аккаунте, может быть несколько RFID, то у вас нет звукового решения, так как nfled rfid может принадлежать любому аккаунту, устройству, RFID.

Примечание: чтобы это работало, у вас должен быть хотя бы один ненулевой rfid в каждой комбо, иначе First() вылетит и сгорит. С другой стороны, если у вас нет ненулевого rfid в combe, нет способа узнать, что это такое, во-первых, можно использовать FirstOrDefault, но тогда вы получите несколько нулевых ключей, по одному для каждой учетной записи, устройства. комбо без RFID.

...