在一个请求中获取 DBRef。扩展参考模式

问题描述 投票:0回答:1

我有相同的产品,在不同的城市以不同的价格出售。

产品.js

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

const ProductSchema = new Schema({
  name: String,
  img: String,
  translations: {
    Spanish: { name: String},
  }
});
module.exports = mongoose.model("products", ProductSchema)

City.js

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

const CitySchema = new Schema({
  name: String,
  products_cost: [{
    product_id: { type: Schema.Types.ObjectId, ref: 'products' },
    price: { type: Number, default: 0 }
  }],
  translations: {
    Spanish: { name: String },
  }
});

module.exports = mongoose.model('cities', CitySchema);

设置产品默认记录:

const Product = require('../models/Product');
const defaultValuesProducts = () => {
    try {
        Product.insertMany([
            {
                name: "Agate",
                img: "img/Agate.png",
                translations: {
                    Spanish: { name: "Ágata" },                 
                }
            },
            {
                name: "Gold",
                img: "img/Gold.png",
                translations: {
                    Spanish: { name: "Oro" },                   
                }
            },
        ]);
    } catch (error) {
        console.log(error);
    }
}
module.exports = {defaultValuesProducts};

我正在尝试链接产品城市。设置城市默认记录:

const Product = require('../models/Product');
const Cities = require('../models/City');

const defaultValuesCities = () => {
    
    try {
        const  products = Product.find();
        Cities.insertMany([
            {
                name: "Amsterdam",
                products_cost: [
                    {
                        product_id: products[0]
                    },
                    {
                        product_id: products[1]
                    }                   
                ],
                shipRoute: 8,
                translations: {
                    Spanish: { name: "Ámsterdam" },                   
                }
            }
        ]);
    } catch (error) {
        console.log(error);
    }
};

module.exports = { defaultValuesCities };

In DB i see all added records:


但我无法直接从城市获取产品:
router.get('', async (req, res) => {
    try {
        const cities = await City.find();
        //const cities = await City.find().populate(products); - ReferenceError: products is not defined
        res.render('index', { cities });
    }
    catch (error) {
        console.log(error);
    }
});
<ol>
    <% cities.forEach(city=> { %>
        <li>
            <%=city.name%>
            <%=city.translations.Spanish.name%>
                <ol>
                    <% city.products_cost.forEach(element=> { %>
                        <li>

                            <%=element.product_id.name%> - How can I get it?

                            <%=element.price%>
                        </li>
                    <% }) %>
                </ol>
        </li>
    <% }) %>
</ol>

请告诉我哪里出错了。如何直接访问 DBRef 对象?

node.js mongodb mongoose mongodb-query mongoose-schema
1个回答
0
投票

您的代码存在几个问题。

  1. 使用以下内容更新
    Product.js
// Change name of Model from 'products' to 'Product'
module.exports = mongoose.model("Product", ProductSchema)
  1. 使用以下内容更新
    City.js
// Change name the ref from 'products' to 'Product'
product_id: { type: Schema.Types.ObjectId, ref: 'Product' },

那是因为:

第一个参数是模型所属集合的单一名称。 Mongoose 会自动查找模型名称的复数小写版本。

  1. 与您的想法相反,您的
    defaultValuesCities()
    函数尚未将相关数据添加到您的
    products_cost
    数组中。是的,其中有两个新对象,但没有
    product_id
    ,只有自动生成的
    _id
    0
    的默认
    price
    值。您的
    Product.find();
    Cities.insertMany()
    函数都是异步操作,因此您的产品将无法及时返回以便在代码的
    Cities.insertMany()
    部分访问值。像这样更新:
const defaultValuesCities = async () => { //< Mark function as async
    
    try {
        const products = await Product.find(); //< Mark function call with await
        await Cities.insertMany([ //< Again, mark function call with await
            {
                name: "Amsterdam",
                products_cost: [
                    {
                        product_id: products[0]._id //< You need to insert the _id ObjectId
                    },
                    {
                        product_id: products[1]._id //< You need to insert the _id ObjectId
                    }                   
                ],
                shipRoute: 8,
                translations: {
                    Spanish: { name: "Ámsterdam" },                   
                }
            }
        ]);
    } catch (error) {
        console.log(error);
    }
};
  1. 由于您的
    product_id
    引用嵌套在
    products_cost
    数组中,因此您需要定义
    populate()
    方法的路径。像这样更新你的路线:
try {
   // You need to use dot notation to access 'products_cost.product_id'
   const cities = await City.find().populate({ path: 'products_cost.product_id', model: Product }); 
   res.render('index', { cities });
} catch (error) {
   console.log(error);
}

© www.soinside.com 2019 - 2024. All rights reserved.