英文:
How to Filter MongoDB Data Based on Array Values?
问题
以下是您要翻译的内容:
我在一个集合中有一个文档,其中有数组中的值。
{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "black", "price": 22000},
{"color": "blue", "price": 21000}
]
},
{
"name": "XYZ",
"details": [
{"color": "yellow", "price": 10000},
{"color": "black", "price": 12000},
{"color": "green","price": 11000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "pink", "price": 32000},
{"color": "blue", "price": 31000}
]
}
我想要过滤红色和蓝色的数据,并需要输出如下:
{"name": "ABC", "color": "red", "price": 20000},
{"name": "ABC", "color": "blue", "price": 21000},
{"name": "CBD", "color": "red", "price": 30000},
{"name": "CBD", "color": "blue", "price": 31000}
有关此查询的MongoDB查询或JS / TS代码,请告诉我...
英文:
I have a document in a collection which have values in array.
{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "black", "price": 22000},
{"color": "blue", "price": 21000}
]
},
{
"name": "XYZ",
"details": [
{"color": "yellow", "price": 10000},
{"color": "black", "price": 12000},
{"color": "green", "price": 11000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "pink", "price": 32000},
{"color": "blue", "price": 31000}
]
}
I want to filter data for color red and blue and need output like
{"name": "ABC", "color": "red", "price": 20000},
{"name": "ABC", "color": "blue", "price": 21000},
{"name": "CBD", "color": "red", "price": 30000},
{"name": "CBD", "color": "blue", "price": 31000}
what will the query for this...
I am able to get
{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "blue", "price": 21000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "blue", "price": 31000}
]
}
but I want like
{"name": "ABC", "color": "red", "price": 20000},
{"name": "ABC", "color": "blue", "price": 21000},
{"name": "CBD", "color": "red", "price": 30000},
{"name": "CBD", "color": "blue", "price": 31000}
let me know the MongoDB query or JS/TS code to simplify array object...
答案1
得分: 1
您可以使用flatMap获取以下所示的所需格式化数据:
const data = [
{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "blue", "price": 21000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "blue", "price": 31000}
]
}
];
const result = data.flatMap(entry => entry.details.map(detail => ({name: entry.name, ...detail})));
console.log(result);
请注意,上述代码是JavaScript代码示例,用于演示如何使用flatMap获得所需格式化数据。
英文:
You can use flatMap to get desired formatted data like below:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const data = [
{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "blue", "price": 21000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "blue", "price": 31000}
]
}
];
const result = data.flatMap(entry => entry.details.map(detail => ({name: entry.name, ...detail})));
console.log(result);
<!-- end snippet -->
答案2
得分: 1
使用 Array.flatMap() 可以实现这个功能,下面是参考链接,你可以查看 flattening-an-array-of-complex-objects-with-an-array-attribute
let data = [
{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "black", "price": 22000},
{"color": "blue", "price": 21000}
]
},
{
"name": "XYZ",
"details": [
{"color": "yellow", "price": 10000},
{"color": "black", "price": 12000},
{"color": "green", "price": 11000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "pink", "price": 32000},
{"color": "blue", "price": 31000}
]
}
]
data = data.filter(d1 => d1.details.some(d2 => d2.color == "red" || d2.color == "blue"))
data = data.flatMap(({ name, details }) => details.map(d => ({ name, ...d })))
console.log(data)
英文:
Using Array.flatMap() can do it ,below is reference for you,you can check at flattening-an-array-of-complex-objects-with-an-array-attribute
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let data = [
{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "black", "price": 22000},
{"color": "blue", "price": 21000}
]
},
{
"name": "XYZ",
"details": [
{"color": "yellow", "price": 10000},
{"color": "black", "price": 12000},
{"color": "green", "price": 11000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "pink", "price": 32000},
{"color": "blue", "price": 31000}
]
}
]
data = data.filter(d1 => d1.details.some(d2 => d2.color == "red" || d2.color == "blue"))
data = data.flatMap(({ name,details }) => details.map(d => ({ name, ...d })))
console.log(data)
<!-- end snippet -->
答案3
得分: 1
我认为,如果你想要获得良好的性能,那么这将是最佳选择:
db.collection.aggregate([
{ $match: { "details.color": { $in: ["red", "blue"] } } },
{
$set: {
details: {
$filter: {
input: "$details",
cond: { $in: ["$$this.color", ["red", "blue"]] }
}
}
}
},
{ $unwind: "$details" },
{ $replaceWith: { $mergeObjects: [{ name: "$name" }, "$details"] } }
])
英文:
I think, if you like to get good performance then this would be the best option:
db.collection.aggregate([
{ $match: { "details.color": { $in: ["red", "blue"] } } },
{
$set: {
details: {
$filter: {
input: "$details",
cond: { $in: ["$$this.color", ["red", "blue"]] }
}
}
}
},
{ $unwind: "$details" },
{ $replaceWith: { $mergeObjects: [{ name: "$name" }, "$details"] } }
])
答案4
得分: 0
你可以运行以下的JavaScript代码(如果你不介意性能):
let initialArr = [{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "blue", "price": 21000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "blue", "price": 31000}
]
}
]
let resultArr = []
for (let i = 0; i < initialArr.length; i++) {
for (let k = 0; k < initialArr[i].details.length; k++) {
resultArr.push({name: initialArr[i].name, ...initialArr[i].details[k]})
}
}
英文:
You can run the below js code (if you don't mind the performance):
let initialArr = [{
"name": "ABC",
"details": [
{"color": "red", "price": 20000},
{"color": "blue", "price": 21000}
]
},
{
"name": "CBD",
"details": [
{"color": "red", "price": 30000},
{"color": "blue", "price": 31000}
]
}
]
let resultArr = []
for (let i = 0; i < initialArr.length; i++) {
for (let k = 0; k < initialArr[i].details.length; k++) {
resultArr.push({name: initialArr[i].name, ...initialArr[i].details[k]})
}
}
答案5
得分: 0
MongoDB的$unwind操作符可以帮助 - > 从输入文档中拆分数组字段,以输出每个元素的文档。每个输出文档都是输入文档,其数组字段的值被元素替换。
以下是一个聚合查询 -
db.getCollection('your_collection').aggregate([
// 为`details`数组中的每个元素创建一个文档
{ $unwind : "$details" },
// 过滤颜色为红色或蓝色的文档
{ $match: { "details.color": { $in: ["red", "blue"] } } },
// 以所需格式输出
{ $project: { name: 1, color: "$details.color", price: "$details.price" } }
])
- 这是拆分后的数据的样子 -
[
{"name": "ABC", "details": { "color": "red", "price": 20000} },
{"name": "ABC", "details": { "color": "blue", "price": 22000} },
{"name": "ABC", "details": { "color": "blue", "price": 21000} },
{"name": "XYZ", "details": { "color": "yellow", "price": 10000} },
{"name": "XYZ", "details": { "color": "black", "price": 12000} },
...
]
- 过滤后的、拆分后的数据(仅红色和蓝色)-
[
{"name": "ABC", "color": "red", "price": 20000},
{"name": "ABC", "color": "blue", "price": 21000},
{"name": "CBD", "color": "red", "price": 30000},
{"name": "CBD", "color": "blue", "price": 31000}
]
英文:
MongoDB's $unwind operator can help -
> Deconstructs an array field from the input documents to output a document for each element. Each output document is the input document with the value of the array field replaced by the element.
Here's an aggregate query -
db.getCollection('your_collection').aggregate([
// create a document for each element in `details` array
{ $unwind : "$details" },
// filter document with color red or blue
{ $match: { "details.color": { $in: ["red", "blue"] } } },
// output in desired format
{ $project: { name: 1, color: "$details.color", price: "$details.price" } }
])
- This is how unwounded data would look like -
[
{"name": "ABC", "details": { "color": "red", "price": 20000} },
{"name": "ABC", "details": { "color": "blue", "price": 22000} },
{"name": "ABC", "details": { "color": "blue", "price": 21000} },
{"name": "XYZ", "details": { "color": "yellow", "price": 10000} },
{"name": "XYZ", "details": { "color": "black", "price": 12000} },
...
]
- Filtered, unwounded data (only red & blue)-
[
{"name": "ABC", "color": "red", "price": 20000},
{"name": "ABC", "color": "blue", "price": 21000},
{"name": "CBD", "color": "red", "price": 30000},
{"name": "CBD", "color": "blue", "price": 31000}
]
答案6
得分: 0
通过使用聚合查询,以下查询对您非常有帮助。
db.collection.aggregate([
{
$unwind: "$details"
},
{
$match: {
"details.color": { $in: ["red", "blue"] }
}
},
{
$project: {
_id: 0,
name: 1,
color: "$details.color",
price: "$details.price"
}
}
]);
英文:
By using aggregate the below query helps you alot.
db.collection.aggregate([
{
$unwind: "$details"
},
{
$match: {
"details.color": { $in: ["red", "blue"] }
}
},
{
$project: {
_id: 0,
name: 1,
color: "$details.color",
price: "$details.price"
}
}
]);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论