簡體   English   中英

填充字段然后找到 - mongoose

[英]Populate field then find - mongoose

我有一個Cheques和一個Payees集合,每張支票都有其對應的Payee ID

我想做的是在支票上寫一些查詢,但我需要在填充收款人后進行搜索(以獲取姓名)

const search = req.query.search || "";
const cheques = await Cheque
    .find({
        isCancelled: false,
        dueDate: { $gte: sinceDate, $lte: tillDate }
    })
    .select("_id serial dueDate value payee")
    .skip(page * limit)
    .limit(limit)
    .sort({ dueDate: -1, serial: 1 })
    .populate({
        path: "payee",
        select: "name"
    })

我想我正在嘗試做的是在我的代碼中的某個地方安裝它,

match: {
    name: { $regex: search, $options: "i" }
   },

我試圖將匹配放入填充中,但即使它們不滿足填充匹配但填充為 null,它仍然會找到所有檢查。

我討厭這個答案,我希望有人會發布一個更好的答案,但我已經在 web 上沖浪了,但沒有運氣。 我能夠找到的唯一方法是在聚合中使用$lookup方法。

因此,您必須將代碼從調用.find()更改為.aggregate()

這不是壞消息,它很好,很穩定,完全沒有問題。 但我討厭那樣,因為它會改變您在代碼中可能遵循的某些模式。

const search = req.query.search || "";
    const cheques = await Cheque
        .aggregate([
             {
               $lookup: { // similar to .populate() in mongoose
                from: 'payees', // the other collection name
                localField: 'payee', // the field referencing the other collection in the curent collection
                foreignField: '_id', // the name of the column where the cell in the current collection can be found in the other collection
                as: 'payee' // the field you want to place the db response in. this will overwrite payee id with the actual document in the response (it only writes to the response, not on the database, no worries)
             },
             { // this is where you'll place your filter object you used to place inside .find()
               $match: {
                 isCancelled: false,
                 dueDate: { $gte: sinceDate, $lte: tillDate }
                 'payee.branch': 'YOUR_FILTER', // this is how you access the actual object from the other collection after population, using the dot notation but inside a string.
               }
             },
             { // this is similar to .select()
               $project: {_id: 1, serial: 1, dueDate: 1, value: 1, payee: 1}
             },
             {
               $unwind: '$payee' // this picks the only object in the field payee: [ { payeeDoc } ] --> { payeeDoc }
             }
        ])
        .skip(page * limit)
        .limit(limit)
        .sort({ dueDate: -1, serial: 1 })

請注意,您如何不能再像以前在.populate()上那樣在 model 查詢上鏈接.select()和 .populate .find() ,因為現在您使用的是.aggregate() ,它返回一個不同的 class 實例mongoose。

  • 如果你願意,你可以調用.projcet()而不是在聚合數組中執行它,但據我所知,你不能使用.select()方法。

我對這個問題的基於意見的解決方案是將您需要過濾的收款人信息包含在 Check 集合中。

在我的 senario 中,當我為了我的用戶角色和權限進行過濾時,就會發生這種情況,因此有人看不到另一個人看到的東西。

這取決於你,但這會讓你以后生成報告時更容易(我假設你正在處理支付服務)。

mongoose 提供的populate()功能首先獲取所有具有給定條件的Cheques ,然后使用_idpayee進行另一個查詢以填充您想要的字段。 https://mongoosejs.com/docs/api.html#query_Query-populate

通過將 match 放入 populate 中,您可以過濾需要填充的支票,而不是支票本身。

一個簡單的解決方案是過濾填充為 null 的支票並將它們返回供您使用。

如果您看到更多此類查詢和/或集合很大,如果符合您的目的,最好將收款人姓名添加到 Checks 集合本身中。

暫無
暫無

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

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