Mongodb $lookup无法使用_id

2cmtqfgy  于 2022-12-12  发布在  Go
关注(0)|答案(9)|浏览(282)

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

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."
    }
xienkqul

xienkqul1#

我终于找到了解决方案,是我的mongoose模式与ObjectId的问题
我改变这个

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},
});

并且正在工作

v1l68za4

v1l68za42#

首先,Assertincharge字段的类型是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:{
  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

a0zr77ik

a0zr77ik3#

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"
    }}
])
zi8p0yeb

zi8p0yeb4#

您只需要使用"_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"
}}

])
对我来说很好。

7z5jn7bk

7z5jn7bk5#

您的查找查询是正确的。但它正在尝试将字符串类型(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"
}}
gywdnpxw

gywdnpxw6#

尝试将incharge的类型(字符串)更改为聚合函数中的ObjectId,如下所示

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

ssgvzors7#

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

pjngdqdw

pjngdqdw8#

如果已将键存储在字符串中,则可以使用$addFields(aggregation)将键转换为objectId

{
        "$addFields": {
            incharge: {
                "$toObjectId": "$incharge"
            }
        }
    }
e1xvtsh3

e1xvtsh39#

试试这个:

{
  from: 'categories',
  let: { cid: { $toObjectId: '$category_id' } },
  pipeline: [
    { $match: { $expr: { $eq: ['$_id', '$$cid'] } } },
  ],
  as: 'category_data'
}

$lookup foreignField is ObjectId

相关问题