无法查询嵌套文档的_id(其他字段有效)

时间:2019-01-24 05:46:54

标签: mongodb mongoose mongodb-query

我想找到vendor._id具有特定值的所有文档。下面是我尝试过的代码,但未返回任何内容。

let name = sampleData.name, _id = sampleData._id
Product.find({"vendor._id":ObjectID(_id)}).then((products) => {
  //returns empty array
})

使用相同的方法,我尝试查询不同的字段,但它可以正常工作。但是我想用_id进行查询,因为其他字段可能会随时间变化。

Product.find({"vendor.name":name}).then((products) => {
  //returns all documents that satisfy the condition.
})

下面是我想find

的示例文档
{
"status" : "active",
"connectedFarms" : [ 
    {
        "_id" : "5c412c62bf8a6602f04ae0bf",
        "status" : "inActive",
        "margin" : 10,
        "price" : 55
    }, 
    {
        "_id" : "5c4567bcb3845b0536a4d92e",
        "status" : "inActive",
        "margin" : 20,
        "price" : 60
    }, 
    {
        "_id" : "5c4567c4b3845b0536a4d931",
        "status" : "active",
        "margin" : 7,
        "price" : 53.5
    }
],
"vendor" : {
    "_id" : ObjectId("5c3fcc0c7657ee02ac24bc21"),
    "name" : "manna"
}
}

这是此文档的架构。

let ProductSchema = new mongoose.Schema({
  vendor:{_id:String, name:String},
  connectedFarms:[{_id:String, name:String, status:String, price:Number, margin:Number}],
  status:{
    type:String,
    trim: true,
    minlength:1
  }
});

1 个答案:

答案 0 :(得分:1)

让我们对此采取不同的方法,并使供应商拥有自己的架构。猫鼬不允许您嵌套架构,因此您不能使vendor._id为真实的ObjectID。

供应商架构

const VendorSchema = new mongoose.Schema({
  name: string
});

module.exports = mongoose.model('Vendor', VendorSchema);

产品架构

const ProductSchema = new mongoose.Schema({
  vendor: {
    type: mongoose.Types.ObjectID,
    ref: 'Vendor'
  },
  connectedFarms: [{
    _id: String,
    name: String,
    status: String,
    price: Number,
    margin: Number
  }],
  status: {
    type: String,
    trim: true,
    minlength: 1
  }
});

module.exports = mongoose.model('Product', ProductSchema);

现在,当您要基于供应商_id查询产品时,这非常简单!您需要做的就是在查询中提供供应商的_id。 注意:因为猫鼬接受字符串并将其稍后转换,所以没有理由在查询中将_id转换为ObjectID。

查询

const vendorID = myVendor._id;
Product.find({ vendor: vendorID })
.then((products) => {
  // Do something with the found products
});

就是这样!数据库中的操作要简单得多,也要清洁得多。供应商字段现在更易于引用。如果需要,您还可以通过填充查询来获取查询中的完整供应商对象。不同之处在于,总体将返回供应商名称和_id,而不仅仅是_id。为此,请运行以下命令:

Product.find({ vendor: vendorID })
.populate('vendor')
.then((products) => {
  // Do something with the populated found products
});