mongodb - mongo 将单个对象转换为一个元素数组
问题描述
我有以下问题。在此示例数据集中:
https://mongoplayground.net/p/itNnrDzZ4JQ
[
{
"name": "test",
"questions": [
{
"headline": "headline 1",
"answer": {
"@id": "001",
"m_IMG": {
"type": "06",
"img": {
"@id": "1111",
"shape": [
{
"@src": "/1_1.jpg",
"@type": "Z05"
},
{
"@src": "/1_2.jpg",
"@type": "Z08"
}
]
}
},
"text": "text1"
}
},
{
"headline": "Headline 2",
"answer": [
{
"@id": "001",
"m_IMG": {
"@type": "24",
"img": {
"@id": "1111",
"shape": {
"@src": "/2_1.jpg",
"@type": "Z05"
}
},
"text": "Test2"
}
},
{
"@id": "002",
"m_IMG": {
"@typeName": "",
"@type": "25",
"img": {
"@id": "2222",
"shape": [
{
"@src": "/2_1.jpg",
"@type": "Z05"
},
{
"@src": "2_2.jpg",
"@type": "Z08"
}
]
}
},
"text": "Test3"
}
]
}
]
}
]
你会发现,如果answer
一个问题只存在一个,它就被表示为一个对象。如果存在多个,则它是一个数组。在shape
节点中也是如此。我想知道将这些节点转换为始终数组的最佳方法是什么(因此,如果存在一个答案,它将是一个元素的数组)。
解决方案
从 MongoDb 版本 >= 4.4 开始,您可以使用$function运算符定义自定义函数以实现 MongoDB 查询语言不支持的行为。尝试这个:
db.collection.aggregate([
{ $unwind: "$questions" },
{
$addFields: {
"questions.answer": {
$function: {
body: function (answers) {
if (Array.isArray(answers)) {
answers.map(function (answer) {
if (!Array.isArray(answer.m_IMG.img.shape)) {
answer.m_IMG.img.shape = [answer.m_IMG.img.shape]
}
})
return answers;
} else {
if (!Array.isArray(answers.m_IMG.img.shape)) {
answers.m_IMG.img.shape = [answers.m_IMG.img.shape]
}
return [answers];
}
},
args: ["$questions.answer"],
lang: "js"
}
}
}
}
]);
输出:
/* 1 createdAt:3/29/2021, 5:57:13 PM*/
{
"_id" : ObjectId("6061c7a1e801471ae43210ae"),
"name" : "test",
"questions" : {
"headline" : "headline 1",
"answer" : [
{
"@id" : "001",
"m_IMG" : {
"type" : "06",
"img" : {
"@id" : "1111",
"shape" : [
{
"@src" : "/1_1.jpg",
"@type" : "Z05"
},
{
"@src" : "/1_2.jpg",
"@type" : "Z08"
}
]
}
},
"text" : "text1"
}
]
}
},
/* 2 createdAt:3/29/2021, 5:57:13 PM*/
{
"_id" : ObjectId("6061c7a1e801471ae43210ae"),
"name" : "test",
"questions" : {
"headline" : "Headline 2",
"answer" : [
{
"@id" : "001",
"m_IMG" : {
"@type" : "24",
"img" : {
"@id" : "1111",
"shape" : [
{
"@src" : "/2_1.jpg",
"@type" : "Z05"
}
]
},
"text" : "Test2"
}
},
{
"@id" : "002",
"m_IMG" : {
"@typeName" : "",
"@type" : "25",
"img" : {
"@id" : "2222",
"shape" : [
{
"@src" : "/2_1.jpg",
"@type" : "Z05"
},
{
"@src" : "2_2.jpg",
"@type" : "Z08"
}
]
}
},
"text" : "Test3"
}
]
}
},
/* 3 createdAt:3/29/2021, 5:57:13 PM*/
{
"_id" : ObjectId("6061c7a1e801471ae43210ae"),
"name" : "test",
"questions" : {
"headline" : "headline 3",
"answer" : [
{
"@id" : "003",
"m_IMG" : {
"@type" : "25",
"img" : {
"@id" : "1221",
"shape" : [
{
"@src" : "/2_6.jpg",
"@type" : "Z07"
}
]
},
"text" : "Test21"
}
}
]
}
}
测试数据:
[
{
"name": "test",
"questions": [
{
"headline": "headline 1",
"answer": {
"@id": "001",
"m_IMG": {
"type": "06",
"img": {
"@id": "1111",
"shape": [
{
"@src": "/1_1.jpg",
"@type": "Z05"
},
{
"@src": "/1_2.jpg",
"@type": "Z08"
}
]
}
},
"text": "text1"
}
},
{
"headline": "Headline 2",
"answer": [
{
"@id": "001",
"m_IMG": {
"@type": "24",
"img": {
"@id": "1111",
"shape": {
"@src": "/2_1.jpg",
"@type": "Z05"
}
},
"text": "Test2"
}
},
{
"@id": "002",
"m_IMG": {
"@typeName": "",
"@type": "25",
"img": {
"@id": "2222",
"shape": [
{
"@src": "/2_1.jpg",
"@type": "Z05"
},
{
"@src": "2_2.jpg",
"@type": "Z08"
}
]
}
},
"text": "Test3"
}
]
},
{
"headline": "headline 3",
"answer": {
"@id": "003",
"m_IMG": {
"@type": "25",
"img": {
"@id": "1221",
"shape": {
"@src": "/2_6.jpg",
"@type": "Z07"
}
},
"text": "Test21"
}
}
}
]
}
]
推荐阅读
- mongodb - Vert.x 假/嵌入式 mongo
- python - ValueError:工作表标题中发现无效字符
- javascript - 如何多次插入
- r - as.Date 不会正确转换完整的书面月份
- node.js - elasticsearch中的连接池
- spring-batch - Spring Batch AmqpItemReader 确认
- ruby-on-rails - 更改了数据库中的列名,现在显示不显示信息
- javascript - TypeError:通过 Selenium 为 Chrome 下载管理器调用 execute_script() 时,“NoneType”对象不可下标
- xcode - Xcode UI 测试不会自动启动模拟器
- jquery - 加载ajax导致布局