Сопоставление составных полей _id в агрегате MongoDB

Я новичок в MongoDB, поэтому, пожалуйста, простите меня, если на этот вопрос есть очевидный ответ...

Контекст:

Я следовал примеру в документации MongoDB для реализации иерархической агрегации. с помощью уменьшения карты. В примере используется «составное» поле _id в качестве ключа уменьшения карты, создающего сводные документы, подобные этому...

{
   _id: { u: "rick", d: ISODate("2010-10-10T14:00:00Z") },
   value: {
       ts: ISODate('2010-10-10T15:01:00Z'),
       total: 254,
       count: 10,
       mean: 25.4 }
}

Это все хорошо и хорошо. Мой конкретный вариант использования требует, чтобы значения для несколько похожих ключей выдавались каждые map шага. Например...

{
   _id: { u: "rick", d: ISODate("2010-10-10T14:00:00Z"), hobby: "wizardry" },
   value: {
       ts: ISODate('2010-10-10T15:01:00Z'),
       total: 254,
       count: 10,
       mean: 25.4 }
}

{
   _id: { u: "rick", d: ISODate("2010-10-10T14:00:00Z"), gender: "male" },
   value: {
       ts: ISODate('2010-10-10T15:01:00Z'),
       total: 254,
       count: 10,
       mean: 25.4 }
}

(Значения те же, но клавиши _id немного отличаются.)

Это тоже хорошо и хорошо.

Вопрос:

Теперь я хотел бы агрегировать свои иерархические коллекции (представления), которые содержат документы, имеющие несколько разных составных _id полей, но только документы с $matching _id полями. Например, я хотел бы агрегировать только документы, имеющие тип {u: String, d: Date, hobby: String} _id, или только документы с типом _id {u: String, d: Date}.

Я знаю, что могу использовать оператор $exists, чтобы ограничить, какие поля _id должны и не должны быть разрешены, но я не хочу создавать отдельную агрегацию для каждого _id (потенциально многих).

Есть ли простой способ программно ограничить $matching документы теми, которые содержат (или не содержат) определенные поля в совокупности?


person jonas    schedule 23.07.2013    source источник


Ответы (1)


Я думаю, что лучший способ решить эту проблему — хранить ваши данные по-другому. Ваш тип «_id» имеет произвольные значения в качестве ключа, и этого вам следует избегать. Я бы, вероятно, сохранил документы как:

{
    _id: { u: "rick", d: ISODate("2010-10-10T14:00:00Z"), type: hobby, value: "wizardry" }
}
{
    _id: { u: "rick", d: ISODate("2010-10-10T14:00:00Z"), type: gender, value: "male" },
}

И тогда ваше совпадение простое, даже без необходимости создавать разные совпадения для каждого типа.

person Derick    schedule 24.07.2013
comment
Справедливо, но что, если мне должно сопоставляться только на основе _id полей? - person jonas; 24.07.2013
comment
В моем случае поля _id не так просты, как я их здесь представил (например, отличаются одним полем). Мой вопрос заключается в том, как $match (возможно, с использованием оператора $exists) на основе полей, присутствующих (и отсутствующих) в поле _id, без необходимости перечисления всех возможных комбинаций полей. Итак, при наличии шаблона _id я хотел бы агрегировать просто документы, имеющие поле _id, соответствующее шаблону. - person jonas; 24.07.2013
comment
Зачем ты все это пишешь в _id? - person Derick; 24.07.2013
comment
Это результат процесса уменьшения карты. - person jonas; 24.07.2013
comment
Я думаю, вы должны нарисовать полную картину того, что вы пытаетесь сделать, поскольку я вижу только небольшую часть, что не является хорошей основой для оказания поддержки! - person Derick; 24.07.2013
comment
Не могли бы вы просто ввести данные и желаемый результат (соответствующий данному входу). Так что можно будет импортировать эти документы и протестировать. - person Fake Fish; 04.05.2016