Mongodb $ lookup不使用_id

时间:2016-06-08 14:33:50

标签: node.js mongodb mongoose

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

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

7 个答案:

答案 0 :(得分:10)

我最终找到了解决方案,我的Schema在使用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},
});

正在运作

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

])

对我来说很好。

答案 4 :(得分:0)

首先,断言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

上面的模型被猫鼬命名为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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

尝试更改充电类型,该类型在集合函数中为ObjectId的字符串 像这样

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