如何使用 mongoose "populate" 指定不同集合中已有文档的路径?

How to use mongoose "populate" to specify the path for already existing document of different collection?

我正在使用 Apollo Graphql、Express-Nodejs、MongoDB 和 Mongoose。我有 2 个集合,即:业务和订单。

这是模型

以下是 graphql 类型:

这里是突变:

createBusiness(
      name: String,
      address: String,
        ): Business

createOrder(
      orderNumber: String,
      businessName: String,
      additionalDetails: String
     ): Order

一个特定的业务可以有多个订单,一个特定的订单必须有一个特定的业务。

我想做的是为商业文档创建一个订单。

情况 1.) 如果业务文档不存在: 那么 createOrder 突变应该创建新的业务文档(通过使用填充)

情况 2.) 但如果业务文档存在,则 createOrder 突变不应该创建新的业务文档,而只添加新订单和对现有业务文档的引用。

有人可以告诉我如何在 graphql 和 mongoose 中实现上述内容吗?任何建议都会有帮助!

这是我的订单突变解析器(它不起作用,不知道为什么!!)

import Order from '../models/Order';
import Business from '../models/Business';

export default {

  Mutation:{
    createOrder(_, {
      orderNumber,
      additionalDetails,
      businessName
    }){
      return Business.findOne({
        businessName: businessName
      })
      .then((exist)=>{

        if (!exist){

          let business_Name = new Business({
            name: businessName
          })

            business_Name.save(function (err){
              if (err) return handleError(err);

              let order = new Order({
                orderNumber: orderNumber,
                businessName: business_Name._id,
                additionalDetails: additionalDetails
              });

              order.save(function (err){
                if (err) return handleError(err);
              });
            });
        }
        if (exist){
         // WHAT SHOULD I DO FOR THIS CASE ??
        }



      });
    },

  }
}

提前致谢!

我稍微修改了案例 1 的逻辑,如果公司名称不存在,则不允许创建订单。好像允许未经授权的人在 order mutation 中创建业务,那么我们可能不得不处理额外的可选参数(仅适用于情况 1),使 "createOrder" mutation 变得更加麻烦且不那么合乎逻辑。

相反,对于案例 1 和案例 2,当业务存在时,我们会用一些有用的消息通知客户用户,我们会:

1.) 首先创建新订单,然后将其推送到业务类型的 "orders" 列表中,然后保存它(因为业务类型需要对其子订单数组的引用)(阅读此内容: Saving Refs to Children )

2.) 然后是时候保存新创建的订单并填充 "businessReference"。

这里是createOrder突变的完整代码...

createOrder:  async(_, {
    orderNumber,
    additionalDetails,
    businessName
  })=>{
  // Check if the business  name exists or not 
    try {
            const business_name = await Business.findOne({
                                  name: businessName
                                  })
      if (!business_name){
        throw new Error ('Business name not found. Please create the Business first !');
      }
  // if the business name exists, then 
  // first create order
        let order = await new Order({
                      orderNumber: orderNumber,
                      businessReference: business_Name._id,  
                      additionalDetails: additionalDetails
                  })

                  business_name.orders.push(order);   // then push this order to child
                  business_name.save();                 // array of Business for referencing
                                                        // it later


          return order.save()                                     //then save the order,
                      .then(res => Order.findById(res._id)          // and populate
                      .populate('businessReference')               
                      .exec())                                   

    }
    catch (error) {
      throw error;
    }
  }

因为 exec() 将 return 承诺只有当它没有任何参数时,所以我 return 这样编辑它。有关此的更多信息,请查看