【问题标题】:Mongodb $lookup Not working with _idMongodb $lookup 不使用 _id
【发布时间】:2016-10-08 21:35:45
【问题描述】:

尝试使用此查询,返回查找为空

db.getCollection('tests').aggregate([
    {$match: {typet:'Req'}},
    {$project: {incharge:1}},
    {$lookup:{
            from: "users",
            localField: "incharge", //this is the _id user from tests
            foreignField: "_id", //this is the _id from users
            as: "user"
    }}
])

返回json

  [
    {
        "_id": "57565d2e45bd27b012fc4db9",
        "incharge": "549e0bb67371ecc804ad23ef",
        "user": []
    },
    {
        "_id": "57565d2045bd27b012fc4cbb",
        "incharge": "549e0bb67371ecc804ad21ef",
        "user": []
    },
    {
        "_id": "57565d2245bd27b012fc4cc7",
        "incharge": "549e0bb67371ecc804ad24ef",
        "user": []
    }
]

我尝试了这篇文章,但什么也没发生 MongoDB aggregation project string to ObjectId 有了这个 MongoDB $lookup with _id as a foreignField in PHP

更新

这是文档“用户”

    {
        "_id" : ObjectId("549e0bb67371ecc804ad24ef"),
        "displayname" : "Jhon S."
    },
    {
        "_id" : ObjectId("549e0bb67371ecc804ad21ef"),
        "displayname" : "George F."
    },
    {
        "_id" : ObjectId("549e0bb67371ecc804ad23ef"),
        "displayname" : "Franc D."
    }

【问题讨论】:

  • 请发布文档示例,因为这将帮助我们帮助您:-)
  • 感谢人添加文档用户

标签: node.js mongodb mongoose


【解决方案1】:

我终于找到了解决方案,是我在猫鼬中使用 ObjectId 的 Schema 的问题

我改这个

var Schema = new Schema({
    name: { type: String, required: true},
    incharge: { type: String, required: true},
});

有了这个

var Schema = new Schema({
    name: { type: String, required: true},
    incharge: { type: mongoose.Schema.ObjectId, required: true},
});

并且正在工作

【讨论】:

  • 我的两个 ID 都是猫鼬对象 ID,但我仍然得到空数组
  • 它返回空数组
  • 能否请您告诉如何在 Shell 上执行此操作
  • 对此我感激不尽!我这辈子都搞不定。干得好!
【解决方案2】:

首先,断言incharge 字段的类型是mongoose.Schema.Types.ObjectId。如果您仍然得到一个空数组,可能是因为您使用的是在 NodeJS 中声明的 schema 名称,而不是 MongoDB 使用的 collection 名称。

来自UserSchema 文件的示例:

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const UserSchema = new Schema({
  name: { 
    type: String, 
    required: true
  },
  incharge: { 
    type: Schema.Types.ObjectId, 
    required: true
  },
})

const User = mongoose.model('User', UserSchema)
module.exports = User

上面的模型被mongoose命名为User,但是mongoDB中对应的集合命名为users。生成的$lookup 写为:

$lookup:{
  from: "users",           // name of mongoDB collection, NOT mongoose model
  localField: "incharge",  // referenced users _id in the tests collection
  foreignField: "_id",     // _id from users
  as: "user"               // output array in returned object
}



https://mongoosejs.com/docs/models.html
https://mongoosejs.com/docs/schematypes.html

【讨论】:

  • 一个人为我改变了一切
【解决方案3】:

比较stringObjectId 不会引发错误,而是在聚合输出文档中发送一个空数组。所以你需要确保你已经将string对象id转换为mongodb的ObjectId

db.getCollection('tests').aggregate([
    {$match: {typet:'Req'}},
    {$set: {incharge: {$toObjectId: "$incharge"} }}, // keep the whole document structure, but replace `incharge` into ObjectId
    {$lookup:{
            from: "users",
            localField: "incharge", //this is the _id user from tests
            foreignField: "_id", //this is the _id from users
            as: "user"
    }}
])

【讨论】:

  • 对我来说就像一个魅力。我可以确认这行得通
【解决方案4】:

您的查找查询是正确的。但它试图将字符串类型(incharge)与 ObjectId(_id)进行比较。将字符串转换为 ObjectId,如下所示。它对我有用。

db.getCollection('tests').aggregate([
{$match: {typet:'Req'}},
{$project: {
   incharge:{
     $toObjectId:"$incharge"
   }
},
{$lookup:{
        from: "users",
        localField: "incharge", //this is the _id user from tests
        foreignField: "_id", //this is the _id from users
        as: "user"
}}

【讨论】:

    【解决方案5】:

    您只需使用"_id.str" 即可完成工作。

    db.getCollection('tests').aggregate([
    {$match: {typet:'Req'}},
    {$project: {incharge:1}},
    {$lookup:{
            from: "users",
            localField: "incharge", //this is the _id user from tests
            foreignField: "_id.str", //this is the _id from users
            as: "user"
    }}
    

    ])

    对我来说很好。

    【讨论】:

    • 非常感谢,它有效,但我有点不同。 foreignField: "_id".toString(), //这是用户的_id
    【解决方案6】:

    尝试在聚合函数中将字符串类型更改为 ObjectId 像这样

    { 
        $project : {
            incharge : {
                $toObjectId : "$incharge"
            }
        }
    }
    

    【讨论】:

      【解决方案7】:

      您的查找查询是完美的,但问题是您将 incharge 作为字符串存储到数据库中,而 _id : ObjectId('theID') 是一个对象,而不仅仅是字符串,您不能将 string (' ') 与 object ({ }) 进行比较。因此,最好的方法是将 incharge 键存储为对象(mongoose.Schema.ObjectId),而不是模式中的字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-20
        • 2016-06-01
        • 2018-08-10
        • 2018-02-06
        • 2020-12-31
        • 2020-09-07
        • 2016-07-12
        • 1970-01-01
        相关资源
        最近更新 更多