简体   繁体   English

Mongodb $lookup 不使用 _id

[英]Mongodb $lookup Not working with _id

wend try with this query, return the lookup is empty尝试使用此查询,返回查找为空

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

return json返回 json

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

i try with this post but nothing happend MongoDB aggregation project string to ObjectId and with this MongoDB $lookup with _id as a foreignField in PHP我尝试使用这篇文章,但没有发生任何事情MongoDB 将项目字符串聚合到 ObjectId并使用此MongoDB $lookup with _id 作为 PHP 中的 foreignField

UPDATE更新

this is the Document "users"这是文件“用户”

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

I finaly found the solution, is a problem with my Schema in mongoose with the ObjectId我终于找到了解决方案,是我的 Schema 在带有 ObjectId 的猫鼬中存在问题

I change this我改变这个

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

with this有了这个

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

and is working并且正在工作

First, assert that the type of the incharge field is mongoose.Schema.Types.ObjectId .首先,断言incharge字段的类型是mongoose.Schema.Types.ObjectId If you still get an empty array back it might be because you are using the schema name you declared in NodeJS instead of the collection name used by MongoDB.如果你仍然得到一个空数组,那可能是因为你使用的是你在 NodeJS 中声明的模式名称,而不是 MongoDB 使用的集合名称。

Example from a UserSchema file:来自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

The model above is named User by mongoose but the corresponding collection in mongoDB is named users .上面的模型由 mongoose 命名为User ,但 mongoDB 中相应的集合命名为users The resulting $lookup is written as:结果$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/models.html
https://mongoosejs.com/docs/schematypes.html https://mongoosejs.com/docs/schematypes.html

Your lookup Query is correct.您的查找查询是正确的。 But it is trying to compare a string type (incharge) with ObjectId (_id).但它试图将字符串类型 (incharge) 与 ObjectId (_id) 进行比较。 Convert the string to ObjectId as shown below.将字符串转换为 ObjectId,如下所示。 It works for me.它对我有用。

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

You just have to use "_id.str" and work will be done.您只需要使用"_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"
}}

]) ])

Works fine for me.对我来说很好用。

Comparing a string with an ObjectId doesn't throw an error, rather sends an empty array in the aggregated output document.stringObjectId进行比较不会引发错误,而是在聚合输出文档中发送一个空数组。 So you need to make sure that you have converted the string object id to mongodb's ObjectId :因此,您需要确保已将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"
    }}
])

Your lookup query is perfect, but the problem is you are storing incharge as string into the db, whereas the _id : ObjectId('theID') is an Object and not just string and you cannot compare a string (' ') with an object ({ }).您的查找查询是完美的,但问题是您将incharge作为字符串存储到数据库中,而 _id : ObjectId('theID') 是一个对象而不仅仅是字符串,您不能将string (' ') 与object ({})。 So, the best way is to store the incharge key as an object( mongoose.Schema.ObjectId ) and not as string in the schema.因此,最好的方法是将incharge键存储为对象( mongoose.Schema.ObjectId )而不是模式中的字符串。

try changing type of incharge which is string to ObjectId in aggregate function like this尝试在这样的聚合函数中将字符串类型的 incharge 更改为 ObjectId

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

If you have stored key in string you can use $addFields (aggregation) to convert the key into objectId如果您已将密钥存储在字符串中,则可以使用 $addFields (聚合)将密钥转换为 objectId

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

try this one:试试这个:

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

$lookup foreignField is ObjectId $lookup foreignField 是 ObjectId

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM