MongoDB嵌套数组查询与更新:获取及修改指定座位数
First, let's translate your Java aggregation logic into a MongoDB shell query that does exactly the same thing:
Aggregation Query (Matching Your Java Code)
db.cities.aggregate([ // Filter to get only the Bangalore city document { $match: { name: "Bangalore" } }, // Unwind the movies array to work with individual movie entries { $unwind: "$movies" }, // Filter to keep only the Avengers movie { $match: { "movies.name": "Avengers" } }, // Unwind the theatres array for that movie { $unwind: "$movies.theatres" }, // Filter to keep only the IMAX theatre { $match: { "movies.theatres.name": "IMAX" } }, // Group by seats (though since we've filtered to one theatre, this just returns the seat value as _id) { $group: { _id: "$movies.theatres.seats" } } ])
This will return { "_id": 50 } just like your Java code does.
Alternative Aggregation Approach (More Direct)
Instead of unwinding multiple times, you can use array operators like $filter and $arrayElemAt to directly target the specific theatre's seats without flattening the arrays:
db.cities.aggregate([ { $match: { name: "Bangalore" } }, { $project: { // First, filter the movies array to get only Avengers targetMovie: { $arrayElemAt: [ { $filter: { input: "$movies", cond: { $eq: ["$$this.name", "Avengers"] } } }, 0 ] }, _id: 0 } }, { $project: { // Then filter the theatres array of that movie to get IMAX targetTheatre: { $arrayElemAt: [ { $filter: { input: "$targetMovie.theatres", cond: { $eq: ["$$this.name", "IMAX"] } } }, 0 ] } } }, { $project: { // Extract just the seats value seats: "$targetTheatre.seats" } } ])
This returns { "seats": 50 }, which is a more straightforward result if you just need the number.
Updating the Seat Count
To update the seats for Bangalore -> Avengers -> IMAX, use MongoDB's positional filtered operators to target the exact nested elements safely:
db.cities.updateOne( // Query to find the correct city document { name: "Bangalore" }, // Update the seats value (replace 55 with your desired new count) { $set: { "movies.$[movie].theatres.$[theatre].seats": 55 } }, // Array filters to match the specific movie and theatre { arrayFilters: [ { "movie.name": "Avengers" }, { "theatre.name": "IMAX" } ] } )
This will only modify the seats count for the specified theatre, leaving all other entries in your arrays untouched.
内容的提问来源于stack exchange,提问作者Deepanshu Gautam

