MongoDB 使用另一个集合中的另一个字段更新字段

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

我有两个收藏:书籍和类别。类别集合表示一个树结构,使它们使用父级和子级进行嵌套类别。

书籍可以有多个类别并将它们存储在数组中。

示例:书籍有类别,我想取消它并将其设置为父类别。

这就是类别集合的填充方式。

db.categories.insertMany([{
    _id: "Space Opera",
    ancestors: ["Science Fiction", "Fiction", "Science Fiction & Fantasy"],
    parent: ["Science Fiction"],
}, {
    _id: "Dystopian",
    ancestors: ["Science Fiction", "Fiction", "Science Fiction & Fantasy"],
    parent: ["Science Fiction"],
}, {
    _id: "Cyberpunk",
    ancestors: ["Science Fiction", "Fiction", "Science Fiction & Fantasy"],
    parent: ["Science Fiction"],
}, {
    _id: "Science Fiction",
    ancestors: ["Fiction", "Science Fiction & Fantasy"],
    parent: ["Fiction", "Science Fiction & Fantasy"],
}, {
    _id: "Fantasy",
    ancestors: ["Science Fiction & Fantasy"],
    parent: ["Science Fiction & Fantasy"],
}, {
    _id: "Science Fiction & Fantasy",
    ancestors: [],
    parent: [],
}, {
    _id: "Fiction",
    ancestors: [],
    parent: [],
}]);

另外,如何查询这个并仅获取值“Science Fiction”(请注意,它存储在数组中)?

db.categories.find({
    _id: "Space Opera"
}, {
    _id: 0, 
    parent: 1
})[0].parent // Did not work  
db.categories.find({
    _id: "Space Opera"
}, {
    _id: 0, 
    parent: 1
}) // find parent

// result 
[
  {
    "parent": [
      "Science Fiction"
    ]
  }
]
db.books.update({
    title: "Book1"
}, {
    $set: {
        category: [**PARENT CATEGORY**]
    }
})

我相信我可以在 books.update() 中使用上面的代码

我可以将其存储在一个单独的变量中,但在 vscode 中它给了我未定义的值。 并且内部查询没有给我前面所说的正确值,但我认为你明白了。

db.books.update({
    title: "Book1"
}, {
    $set: {
        category: [
            db.categories.find({
                _id: "Space Opera"
            }, {
                _id: 0, 
                parent: 1
            })
        ]
    }
})
mongodb collections nosql
2个回答
3
投票

您可以通过此聚合管道获得的父级:

db.categories.aggregate([
   { $match: { _id: "Space Opera" } },
   { $project: { _id: 0, parent: { $first: "$parent" } } }
])

甚至

db.categories.aggregate([
   { $match: { _id: "Space Opera" } },
   { $project: { _id: 0, parent: { $first: "$parent" } } }
]).toArray().shift().parent

为了加入集合,您必须使用 $lookup 运算符。请记住,像 MongoDB 这样的 NoSQL 数据库并未针对连接/查找进行优化。在现实生活中,您应该寻找更好的设计。

db.books.aggregate([
   { $match: { title: "Book1" } },
   {
      $lookup:
         {
            from: "categories",
            pipeline: [
               { $match: { _id: "Space Opera" } },
               { $project: { _id: 0, parent: { $first: "$parent" } } }
            ],
            as: "category"
         }
   },
   { $set: { category: { $first: "$category.parent" } } }
])

如果您想更新现有集合,那么您必须为其创建一个循环:

db.books.aggregate([...]).forEach(function (doc) {
   db.books.updateOne({ _id: doc._id }, { $set: { category: doc.category } });
})

0
投票

我必须更新城市表中的州 ID,所以我尝试了这个,它正在工作:

  1. 州名称匹配的地方

  2. 从州表id更新城市表中的州id

    db.states.find({}, { state:1, _id:1}).forEach(function (sts) {
      db.cities.updateMany(
        { state: sts.state },    
        { $set: { state_id: sts._id}}
      )
    })
    

SQL

Update Cities 
Set State_Id = States._Id
From Cities
INNER JOIN States ON Cities.State = States.State
© www.soinside.com 2019 - 2024. All rights reserved.