Используйте поля, которые начинаются с $ в поиске агрегации MongoDB - PullRequest
0 голосов
/ 31 октября 2019

У меня есть база данных MongoDB, которая заполняется приложением Spring с использованием Spring Data. Я хочу выполнить ручной запрос, чтобы объединить две коллекции и извлечь некоторую статистику из этих данных.

Первая коллекция называется emailCampaign и содержит эту информацию (упрощенно):

{
    "_id" : ObjectId("5db85687307b0a0d184448db"),
    "name" : "Welcome email",
    "subject" : "¡Welcome {{ user.name }}!",
    "status" : "Sent",
    "_class" : "com.mycompany.EmailCampaign"
}

Вторая коллекция называется campaignDelivery и содержит эту информацию (упрощенно):

/* 1 */
{
    "_id" : ObjectId("5db183fb307b0aef3113361f"),
    "campaign" : {
        "$ref" : "emailCampaign",
        "$id" : ObjectId("5db85687307b0a0d184448db")
    },
    "deliveries" : 3,
    "_class" : "com.mycompany.CampaignDelivery"
}

/* 2 */
{
    "_id" : ObjectId("5db85f2c307b0a0d184448e1"),
    "campaign" : {
        "$ref" : "emailCampaign",
        "$id" : ObjectId("5db85687307b0a0d184448db")
    },
    "deliveries" : 5,
    "_class" : "com.mycompany.CampaignDelivery"
}

В конечном итоге я хочу получить сумму обоих полей deliveries, но сейчас я застрял с основным JOIN:

db.emailCampaign.aggregate([
{
    $lookup: {
        from: 'campaignDelivery',
        localField: '_id',
        foreignField: 'campaign.$id',
        as: 'deliveries'
    }
}
])

Выдает следующую ошибку:

Имена полей FieldPath могут не начинаться с '$'.

Выход из доллара не оказал влиянияи я не могу привести примеры полей, начинающихся с долларов.

1 Ответ

1 голос
/ 31 октября 2019

Вы можете обойти это, используя некоррелированный $ lookup с $ objectToArray в подзапросе для доступа campaign.$id:

db.emailCampaign.aggregate([
  { $lookup: {
    from: "campaignDelivery",
    let: { id: "$_id" },
    pipeline: [
      { $addFields: {
        refId: { $arrayElemAt: [
          { $filter: {
            input: { $objectToArray: "$campaign" },
            cond: { $eq: [ "$$this.k", { $literal: "$id" } ] }
          } }
          , 0
        ] }
      } },
      { $match: {
        $expr: { $eq: [
          "$refId.v",
          "$$id"
        ] }
      } },
      { $project: {
        refId: 0
      } }
    ],
    as: "deliveries"
  } }
])
...