Node.js Mongoose populate()未按预期工作

Node.js Mongoose populate()未按预期工作,node.js,mongodb,express,mongoose,mongoose-populate,Node.js,Mongodb,Express,Mongoose,Mongoose Populate,我有一张PaymentCard和一个用户模式,并希望在创建新的PaymentCard记录以将特定卡链接到特定客户时定义现有用户的ID。它确实使用客户的mongoID创建PaymentCard文档,但是使用.populate()查询不会在任何用户上返回任何卡片,并且在所有用户上返回空数组 参考应该是模型,而不是基础集合,因此在本例中,参考是'PaymentCard',而不是'paymentcards' 因为你要寻找一个无界的1-N关系,这可以用猫鼬来解决 在您的客户模式上: const Custo

我有一张PaymentCard和一个用户模式,并希望在创建新的PaymentCard记录以将特定卡链接到特定客户时定义现有用户的ID。它确实使用客户的mongoID创建PaymentCard文档,但是使用.populate()查询不会在任何用户上返回任何卡片,并且在所有用户上返回空数组

  • 参考应该是模型,而不是基础集合,因此在本例中,参考是
    'PaymentCard'
    ,而不是
    'paymentcards'
  • 因为你要寻找一个无界的
    1-N
    关系,这可以用猫鼬来解决
  • 在您的
    客户
    模式上:

    const Customer = new Schema({
    ...
    });
    
    
    Customer.virtual('cards', {
      ref: 'PaymentCard',
      localField: '_id',
      foreignField: 'owner',
      justOne: false
    });
    
    module.exports = ...
    
    然后您可以使用
    .populate('cards')
    来获取虚拟文档的内容

  • 参考应该是模型,而不是基础集合,因此在本例中,参考是
    'PaymentCard'
    ,而不是
    'paymentcards'
  • 因为你要寻找一个无界的
    1-N
    关系,这可以用猫鼬来解决
  • 在您的
    客户
    模式上:

    const Customer = new Schema({
    ...
    });
    
    
    Customer.virtual('cards', {
      ref: 'PaymentCard',
      localField: '_id',
      foreignField: 'owner',
      justOne: false
    });
    
    module.exports = ...
    

    然后,您可以使用
    .populate('cards')
    来获取虚拟卡的内容要能够从用户那里填充卡,您需要在创建付款时将卡id推送到用户卡数组。但是我在你的
    addPayment
    中看不到这种逻辑

    此外,如前所述,您需要更正您的用户架构,对于用户架构中的卡,ref必须是
    “PaymentCard”
    。(对于PaymentCard,您需要将customer的ref改为
    “customer”

    为了方便起见,我将排除jwt.verify部分,并描述我的解决方案

    如前所述,您需要将创建的卡id保存到用户的卡阵列:

    router.post(“/addPayment”),异步(req,res)=>{
    试一试{
    const result=wait PaymentCard.create(请求主体);
    const customerId=req.body.owner;
    const response=wait Customer.findByIdAndUpdate(
    客户ID,
    {
    $push:{cards:result.\u id}//result.\u id具有新创建的卡的值
    },
    {新:正确}
    );
    res.send(响应);
    }捕捉(错误){
    控制台日志(err);
    res.status(500)。发送(“出错”);
    }
    });
    
    假设您的客户没有任何卡:

    {
        "cards": [],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    
    当我们在邮寄路线中添加卡片时,该客户将如下所示:

    {
        "cards": [
            "5e82400776322539e0fb1669"
        ],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    
    router.get("/getAll", async (req, res) => {
      try {
        const customerId = "5e823f6f76322539e0fb1668";
    
        const result = await Customer.findById(customerId).populate("cards");
    
        res.send(result);
      } catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
      }
    });
    
    添加的卡片文档为:

    {
        "owner": "5e823f6f76322539e0fb1668",
        "nameOnCard": "John Smith",
        "cardNumber":"1234123412341234",
        "cardIssuer": "VISA",
        "cvc": 123,
        "exp": 202008
    }
    
    现在,您可以这样填充用户卡:

    {
        "cards": [
            "5e82400776322539e0fb1669"
        ],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    
    router.get("/getAll", async (req, res) => {
      try {
        const customerId = "5e823f6f76322539e0fb1668";
    
        const result = await Customer.findById(customerId).populate("cards");
    
        res.send(result);
      } catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
      }
    });
    
    这将为您提供以下结果:

    {
        "cards": [
            {
                "_id": "5e82400776322539e0fb1669",
                "owner": "5e823f6f76322539e0fb1668",
                "nameOnCard": "John Smith",
                "cardNumber": "1234123412341234",
                "cardIssuer": "VISA",
                "cvc": 123,
                "exp": 202008,
                "__v": 0
            }
        ],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    

    为了能够从用户填充卡,您需要在创建付款时将卡id推送到用户卡阵列。但是我在你的
    addPayment
    中看不到这种逻辑

    此外,如前所述,您需要更正您的用户架构,对于用户架构中的卡,ref必须是
    “PaymentCard”
    。(对于PaymentCard,您需要将customer的ref改为
    “customer”

    为了方便起见,我将排除jwt.verify部分,并描述我的解决方案

    如前所述,您需要将创建的卡id保存到用户的卡阵列:

    router.post(“/addPayment”),异步(req,res)=>{
    试一试{
    const result=wait PaymentCard.create(请求主体);
    const customerId=req.body.owner;
    const response=wait Customer.findByIdAndUpdate(
    客户ID,
    {
    $push:{cards:result.\u id}//result.\u id具有新创建的卡的值
    },
    {新:正确}
    );
    res.send(响应);
    }捕捉(错误){
    控制台日志(err);
    res.status(500)。发送(“出错”);
    }
    });
    
    假设您的客户没有任何卡:

    {
        "cards": [],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    
    当我们在邮寄路线中添加卡片时,该客户将如下所示:

    {
        "cards": [
            "5e82400776322539e0fb1669"
        ],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    
    router.get("/getAll", async (req, res) => {
      try {
        const customerId = "5e823f6f76322539e0fb1668";
    
        const result = await Customer.findById(customerId).populate("cards");
    
        res.send(result);
      } catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
      }
    });
    
    添加的卡片文档为:

    {
        "owner": "5e823f6f76322539e0fb1668",
        "nameOnCard": "John Smith",
        "cardNumber":"1234123412341234",
        "cardIssuer": "VISA",
        "cvc": 123,
        "exp": 202008
    }
    
    现在,您可以这样填充用户卡:

    {
        "cards": [
            "5e82400776322539e0fb1669"
        ],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    
    router.get("/getAll", async (req, res) => {
      try {
        const customerId = "5e823f6f76322539e0fb1668";
    
        const result = await Customer.findById(customerId).populate("cards");
    
        res.send(result);
      } catch (err) {
        console.log(err);
        res.status(500).send("Something went wrong");
      }
    });
    
    这将为您提供以下结果:

    {
        "cards": [
            {
                "_id": "5e82400776322539e0fb1669",
                "owner": "5e823f6f76322539e0fb1668",
                "nameOnCard": "John Smith",
                "cardNumber": "1234123412341234",
                "cardIssuer": "VISA",
                "cvc": 123,
                "exp": 202008,
                "__v": 0
            }
        ],
        "_id": "5e823f6f76322539e0fb1668",
        "name": "John",
        "surname": "Smith",
        "customerStatus": "Regular",
        "email": "john@test.com",
        "phoneNo": "123123123",
        "__v": 0
    }
    

    我已经尝试引用该模型,但是它仍然不会在每个用户的cards数组中返回任何内容。您确定客户的cards属性包含任何内容吗?或者只是支付卡上的所有者财产?如果是这种情况,我怀疑您正在为cards数组寻找一个而不是一个ref。是的,每当我发出POST请求以注册一张新卡并提供现有用户的mongoID时,它都会作为ObjectID保存在新PaymentCard的owner字段中。但是,在获取客户列表的GET调用中,每个客户上的cards数组保持为空,即使使用populate()命令功能我认为问题在于,您没有更新所有者的
    ,也没有包括新的
    支付卡
    的id。填充者正在查看
    数组,以确定连接到哪个id的
    支付卡
    。如果数组为空,则不会填充任何内容。我更新了我的答案,加入了
    virtual
    definition.Hey。使用您建议的虚拟路径会引发错误:虚拟路径“cards”与架构中的真实路径冲突,但是当我从架构中删除“cards”字段时,它不会执行任何操作,并且当获取所有用户的列表时,不会填充/包括resI中的数组。我已尝试引用该模型,但是,对于每个用户,它仍然不会在cards数组中返回任何内容您确定customer上的cards属性包含任何内容吗?或者只是支付卡上的所有者财产?如果是这种情况,我怀疑您正在为cards数组寻找一个而不是一个ref。是的,每当我发出POST请求以注册一张新卡并提供现有用户的mongoID时,它都会作为ObjectID保存在新PaymentCard的owner字段中。但是,在获取客户列表的GET调用中,每个客户上的cards数组保持为空,即使使用populate()函数,我认为问题在于您没有更新