簡體   English   中英

MongoDB $lookup 管道匹配 _id 不起作用

[英]MongoDB $lookup pipeline match by _id not working

我正在嘗試在集合中執行$lookup並將一些數據添加到我的文檔中。 問題是當我嘗試通過_id匹配我的$lookup管道時,它返回一個空數組。 這是我的代碼:

Schedule.aggregate([{ // My Schedule schema
  $match: {
    store: req.query.store,
    "customer.id": req.query.user
  }
},
{
  $skip: +req.query.skip
}, {
  $limit: +req.query.limit
},
{
  $lookup: {
    from: Employee.collection.name, // "employee" schema,
    let: {
      id: "$employee.id" // employee _id from the "schedule" collection match above
    },
    pipeline: [{
        $match: {
          $expr: {
            "_id": "$$id" // here i try to match by _id
          }
        }
      },
      {
        $project: { // the only fields i need
          "_id": 1,
          "avatar": 1,
          "name": 1
        }
      }
    ],
    as: "employees" // employees is returned as []
  }
}
]).exec((err, resolve) => {
  if (err) console.log('error', err);
  res.json(resolve);
});

如果它有幫助,這里是我在此聚合中使用的兩個集合:

計划架構:

const ScheduleSchema = new Schema({
  store: {
    type: String,
    required: true
  },
  customer: {
    id: {
      type: String
    },
    name: {
      type: String
    },
    avatar: String,
    phone: {
      type: String
    },
    email: { type: String },
    doc: {
      type: String
    },
  },
  employee: {
    id: {
      type: mongoose.Schema.Types.ObjectId,
      required: true
    },
    name: {
      type: String,
      required: true
    },
    avatar: String,
  },
  service: {
    id: {
      type: String
    },
    name: {
      type: String,
      required: true
    },
    filters: [String]
  },
  info: {
    channel: {
      type: String,
      required: true,
      default: 'app'
    },
    id: mongoose.Schema.Types.ObjectId,
    name: String
  },
  scheduleDate: {
    type: String,
    required: true
  },
  scheduleStart: {
    type: String,
    required: true
  },
  scheduleEnd: {
    type: String,
    required: true
  },
  value: {
    type: Number
  },
  comissionType: {
    type: String,
    default: '$'
  },
  comissionValue: {
    type: Number,
    default: 0
  },
  status: {
    type: Number,
    required: true
  },
  observation: String,
  paymentMethod: {
    type: Number,
    default: 0
  },
  paymentValue: String,
  paymentChange: String,
  color: String
}, {
    timestamps: {
      createdAt: 'created',
      updatedAt: 'updated'
    }
  });

員工架構:

const EmployeeSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  a_to_z: String, // nome normalizado, só minusculas e sem espaços
  description: String,
  email: {
    type: String,
    required: true
  },
  avatar: String,
  phone: {
    type: String
  },
  storeOwner: {
    type: Boolean,
    required: true
  },
  permissions: [
    {
      route: String,
      hasPermission: Boolean
    }
  ],
  scheduleAutomatic: {
    type: Boolean,
    required: true,
    default: false
  },
  password: {
    passwordHash: String,
    salt: String
  },
  active: {
    type: Boolean,
    default: true
  },
  storeKey: {
    type: String,
    required: true
  },
  notification_token: String,
  notification_tokens: {
    type: [String],
    default: []
  },
  workingHours: [{
    weekDay: {
      type: Number,
    },
    doesWork: {
      type: Boolean,
    },
    startHour: String,
    endHour: String,
    lunchStart: String,
    lunchEnd: String
  }],
  config: {
    available_days: {
      type: Number,
      default: 365
    },
    in_advance_schedule: {
      type: Number,
      default: 0
    },
    in_advance_interval: {
      type: String,
      default: 'minute'
    }
  }
}, {
  timestamps: {
    createdAt: 'created',
    updatedAt: 'updated'
  } 
});

編輯

我想要達到的結果是這樣的: 結果示例

employees屬性是我試圖使用$lookup獲取的屬性,它將具有與employee屬性相同的數據,最終它將是一個對象數組,其中只有一個對象。

一些示例文檔:

日程:

color: "lavander",
created: "2018-07-31T18:50:53.423Z",
customer: {id: "5b60a67206e8a65f48a15f13", name: "Gabriel Barreto", phone: "11995274098", cpf: "40735255814"},
employee: {id: "5b2952c68424872fccece7f5", name: "Gabriel Barreto", avatar: null},
observation: "teste",
scheduleDate: "2018-08-01",
scheduleEnd: "2018-08-01 08:30",
scheduleStart: "2018-08-01 08:00",
service: {filters: Array(3), id: "5b606e8cc59e82354cc931e2", name: "Corte Masc"},
status: 1,
store: "5b16cceb56a44e2f6cd0324b",
updated: "2018-11-27T13:27:40.310Z",
value: 25,
__v: 0,
_id: "5b60af8de558661acc5d70b9"

員工:

a_to_z: "gabrielbarreto",
active: true,
avatar: "gabriel_barreto_h7qvcn.jpg",
config: {available_days: 180, in_advance_schedule: 10, in_advance_interval: "hour"},
created: "2018-06-19T19:00:22.315Z",
currency: "BRL",
description: "Novo perfil",
email: "gabriel.barreto@wabiz.com.br",
lang: "pt-BR",
name: "Gabriel Barreto",
notification_token: "2d768670-6011-4873-846d-39580b0d82d0",
notification_tokens: ["53049a82-53dc-4bc3-9646-7a4bee1f367b"],
password: null,
permissions: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
phone: "11995274098",
scheduleAutomatic: false,
storeKey: "5b16cceb56a44e2f6cd0324b",
storeOwner: true,
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImdhYnJpZWwuYmFycmV0b0B3YWJpei5jb20uYnIiLCJpYXQiOjE1NTA2NzEwNDQsImV4cCI6MTU1MzI2MzA0NH0.0Odizd8pS4WPGSqm_2_XrTw1YE8NMOOXnHIrG-WVxGo",
updated: "2019-02-20T13:34:20.619Z",
workingHours: (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
__v: 0,
_id: "5b2952c68424872fccece7f5"

謝謝你的時間

我在使用 $lookup 和 mongoose 嘗試匹配 _id 時也遇到了麻煩,因為我的集合將引用存儲為 String 而不是 ObjectId

模型 A:{_id: ObjectId("xxx"), b_id: "eeeee"}

模型 B:{_id: ObjectId("eeeee")}

MyCollectionA.aggregate([
   {
      $lookup: {
        from: "collectionb",
        let: {id: "$b_id"},
        pipeline: [{$match: {$expr: {$eq: ["$_id", "$$id"]}}}],
        as: b
      }
])

在這個例子中,b 永遠不會被填充,因為 $$id 不被認為是一個 ObjectId

只需添加一個項目來轉換 objectId 中的 $$id 及其工作

MyCollectionA.aggregate([
   {
      $lookup: {
        from: "collectionb",
        let: {id: "$b_id"},
        pipeline: [
           {$project: {_id: 1, bid: {"$toObjectId": "$$id"}}},
           {$match: {$expr: {$eq: ["$_id", "$bid"]}}}
        ],
        as: b
      }
])

或者使用foreignField,localField:

MyCollectionA.aggregate([
   {
      $project:{
        _id: 1,
        b_id: {"$toObjectId": "$b_id"}
      }
   },
   {
      $lookup: {
        from: "collectionb",
        localField: "b_id",
        foreignField: "_id",
        as: b
      }
])

這對我有用:

MyCollectionA.aggregate([
   {
      $lookup: {
        from: "collectionb",
        let: {id: "$b_id"},
        pipeline: [
           {$match: {$expr: {$eq: ["$_id", {"$toObjectId": "$$id"}]}}}
        ],
        as: b
      }
])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM