最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

如何在mongodb中加入对象引用数组

网站源码admin25浏览0评论

如何在mongodb中加入对象引用数组

如何在mongodb中加入对象引用数组

我有一个对象(配方)的集合,该对象具有对另一个集合(成分)的对象引用的数组。我想在数据库层(而不是应用程序层)上将这两者结合在一起。我相信$ aggregate是我需要使用的,但不幸的是并没有取得太大的成功。接下来,您可以找到我的模型,如何在JS中进行联接以及如何在尝试使用$ aggregate实施时陷入困境

TS型号:

export type Ingredient = {
  id?: string;
  name: string;
};

export type IngredientAmount = {
  ingredient: Ingredient;
  amount: number;
  unit: string;
};

export type Recipe {
  id?: number;
  name: string;
  steps: string[];
  ingredients: IngredientAmount[];
}

因为我需要根据成分进行查询,即“给我所有使用牛奶的食谱”,所以我决定使用Document references。但是现在我很难提出一个查询来对此成分数量数组进行联接。

这是数据库条目的外观:

recipes: {
"_id": {
    "$oid": "5eab14eb597fdf1af2974a55"
},
"name": "Cheese & Ham sandwich",
"steps": ["Slice bread", "Put cheese slices and Ham between bread slices"],
"ingredients": [{
    "ingredientId": "5eab10d5597fdf1af2974a4f",
    "amt": "2",
    "unit": "slices"
}, {
    "ingredientId": "5eab10e5597fdf1af2974a50",
    "amt": "1",
    "unit": "unit"
}, {
    "ingredientId": "5eab10fc597fdf1af2974a51",
    "amt": "1",
    "unit": "slice"
},]}

ingredients: {
    "_id": {
        "$oid": "5eab10d5597fdf1af2974a4f"
    },
    "name": "cheese",
}

我想查询这两个文档并根据我的预定义类型将它们加入。这就是我在JS中执行的操作:

// Query recipe
const rawRecipe = await db
  .collection('recipes')
  .findOne(new ObjectID(queryId));

// Get ids to join
const ingredientIds = await rawRecipe['ingredients'].map(
  (i: { ingredientId: string }) => new ObjectID(i.ingredientId)
);

// Fetch the ingredients to be joined
const rawIngredients: Ingredient[] = await db
  .collection('ingredients')
  .find({ _id: { $in: ingredientIds } })
  .map((r) => {
    return {
      id: r._id.toString(),
      name: r.name,
    };
  })
  .toArray();

// Create objects from the items to be joined
const ingredients: IngredientAmount[] = rawIngredients.map((i) => {
  return {
    ingredient: i,
    amount: rawRecipe['ingredients'].find(
      (entry: { ingredientId: string }) => entry.ingredientId == i.id
    ).amt,
    unit: rawRecipe['ingredients'].find(
      (entry: { ingredientId: string }) => entry.ingredientId == i.id
    ).unit,
  };
});

// Create new result object
const r: Recipe = new Recipe(
  rawRecipe['name'],
  rawRecipe['steps'],
  ingredients,
  rawRecipe['_id']
);

使用聚合管道等于什么?

我到了

[
  {
    '$unwind': {
      'path': '$ingredients'
    }
  }, {
    '$addFields': {
      'ingredientOid': {
        '$toObjectId': '$ingredients.ingredientId'
      }
    }
  }, {
    '$lookup': {
      'from': 'ingredients', 
      'localField': 'ingredientOid', 
      'foreignField': '_id', 
      'as': 'ingredientObj'
    }
  }, {
    '$unwind': {
      'path': '$ingredientObj'
    }
  },
]

但是我被困在将其合并回一个文档中。另外,这也不是很有效。

回答如下:

您可以尝试]]

$ lookup或虚拟后备人口

发布评论

评论列表(0)

  1. 暂无评论