mongodb 如何访问多嵌套文档中的数据?
How to access the data in multi nested document in mongodb?
我需要通过省略嵌套文档的某些字段来访问多嵌套子文档中的数据。架构如下所示,预期的输出也如下所示。由于不能在嵌套级别使用投影,所以我该怎么做?
下面给出的是具有嵌套条目的数据库模式,如图所示。
[
{
"_id": {
"$oid": "60e519db4e0f140328adc7c7"
},
"trans": {
"en": {
"name": "Graphics And Design",
"description": "Graphics And Design"
},
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"slug": "graphics-and-design",
"image": "",
"created_at": {
"$numberDouble": "1625627099104.0"
},
"subcategories": [
{
"trans": {
"en": {
"name": "LOGO DESIGN",
"description": "LOGO DESIGN"
},
"fr": {
"name": "LOGO DESIGN",
"description": "LOGO DESIGN"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "logo-design",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e61"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "3D logo",
"description": "3D logo design"
},
"fr": {
"name": "3D logo",
"description": "3D logo design"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e60"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
},
{
"trans": {
"en": {
"name": "BRAND STYLE GUIDES",
"description": "BRAND STYLE GUIDES"
},
"fr": {
"name": "BRAND STYLE GUIDES",
"description": "BRAND STYLE GUIDES"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "brand-style-guides",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e63"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "Brand style 1",
"description": "Brand style 1"
},
"fr": {
"name": "Brand style 1",
"description": "Brand style 1"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
},
{
"trans": {
"en": {
"name": "Brand style 2",
"description": "Brand style 2"
},
"fr": {
"name": "Brand style 2",
"description": "Brand style 2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
}
],
"updated_at": {
"$date": {
"$numberLong": "1625627153547"
}
}
},
//this is the another category
{
"_id": {
"$oid": "60e519db4e0f140328adc7c8"
},
"trans": {
"en": {
"name": "Graphics And Design2",
"description": "Graphics And Design2"
},
"fr": {
"name": "Graphics And Design2",
"description": "Graphics And Design2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"slug": "graphics-and-design2",
"image": "",
"created_at": {
"$numberDouble": "1625627099104.0"
},
"subcategories": [
{
"trans": {
"en": {
"name": "LOGO DESIGN2",
"description": "LOGO DESIGN2"
},
"fr": {
"name": "LOGO DESIGN2",
"description": "LOGO DESIGN2"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "logo-design2",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e61"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "3D logo2",
"description": "3D logo design2"
},
"fr": {
"name": "3D logo2",
"description": "3D logo design2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e60"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
},
{
"trans": {
"en": {
"name": "BRAND STYLE GUIDES2",
"description": "BRAND STYLE GUIDES2"
},
"fr": {
"name": "BRAND STYLE GUIDES2",
"description": "BRAND STYLE GUIDES2"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "brand-style-guides2",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e63"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "Brand style 12",
"description": "Brand style 12"
},
"fr": {
"name": "Brand style 12",
"description": "Brand style 12"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
},
{
"trans": {
"en": {
"name": "Brand style 22",
"description": "Brand style 22"
},
"fr": {
"name": "Brand style 22",
"description": "Brand style 22"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
}
],
"updated_at": {
"$date": {
"$numberLong": "1625627153547"
}
}
}
]
到目前为止我尝试过的代码:
const client = await Database.connect();
const lang = "en";
const r = await client
.collection("categories")
.aggregate([
{
$addFields: {
categories: {
$map: {
input: "$categories",
as: "c",
in: {
$mergeObjects: [
"$$this",
{
trans: `$$c.trans.${lang}`,
subcategories: {
$map: {
input: "$subcategories",
as: "s",
in: {
$mergeObjects: [
"$$this",
{
trans: `$$s.trans.${lang}`,
service_type: {
$map: {
input: "$$s.service_type",
as: "d",
in: {
$mergeObjects: [
"$$this",
{ trans: `$$d.trans.${lang}` },
],
},
},
},
},
],
},
},
},
},
],
},
},
},
},
},
])
.toArray();
console.log(r);
console.log(r)
的回复:
:: FieldPath field names may not start with '$'
预期输出:
[
{
"_id": ObjectId("60e519db4e0f140328adc7c7"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627099104.0"
},
"image": "",
"is_visible": true,
"slug": "graphics-and-design",
"subcategories": [
{
"_id": ObjectId("60e51a116678530e84ee2e61"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e60"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "service_type1",
"trans": {
"description": "service_type1",
"name": "service_type1"
}
}
],
"slug": "logo-design",
"trans": {
"description": "LOGO DESIGN",
"name": "LOGO DESIGN"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e63"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_BRAND STYLE GUIDES",
"name": "ServiceType1_BRAND STYLE GUIDES"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType2_BRAND STYLE GUIDES",
"name": "ServiceType2_BRAND STYLE GUIDES"
}
}
],
"slug": "brand-style-guides",
"trans": {
"description": "BRAND STYLE GUIDES",
"name": "BRAND STYLE GUIDES"
}
}
],
"trans": {
"description": "Graphics And Design",
"name": "Graphics And Design"
},
"updated_at": ISODate("2021-07-07T03:05:53.547Z")
},
{
"_id": ObjectId("60e519db4e0f140328adc7c8"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627099104.0"
},
"image": "",
"is_visible": true,
"slug": "graphics-and-design2",
"subcategories": [
{
"_id": ObjectId("60e51a116678530e84ee2e61"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e60"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_LOGO DESIGN2",
"name": "ServiceType1_LOGO DESIGN2"
}
}
],
"slug": "logo-design2",
"trans": {
"description": "LOGO DESIGN2",
"name": "LOGO DESIGN2"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e63"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_BRAND STYLE GUIDES2",
"name": "ServiceType1_BRAND STYLE GUIDES2"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType2_BRAND STYLE GUIDES2",
"name": "ServiceType2_BRAND STYLE GUIDES2"
}
}
],
"slug": "brand-style-guides2",
"trans": {
"description": "BRAND STYLE GUIDES2",
"name": "BRAND STYLE GUIDES2"
}
}
],
"trans": {
"description": "Graphics And Design2",
"name": "Graphics And Design2"
},
"updated_at": ISODate("2021-07-07T03:05:53.547Z")
}
]
请使用任何好的有效方法帮助解决此问题。
我没有得到你的尝试,你可以试试下面的方法,
$map
迭代 subcategories
数组 的循环
$map
迭代 service_type
数组 的循环
- select
trans
输入语言的对象
$mergeObjects
合并更新的 trans
字段和 service_type
数组 的当前对象
$mergeObjects
将更新的 trans
和 service_type
数组与 subcategories
数组 的当前对象合并
var lang = "en";
const r = await client.collection("categories").aggregate([
{
$addFields: {
trans: "$trans.en",
subcategories: {
$map: {
input: "$subcategories",
as: "s",
in: {
$mergeObjects: [
"$$s",
{
trans: `$$s.trans.${lang}`,
service_type: {
$map: {
input: "$$s.service_type",
in: {
$mergeObjects: ["$$this", { trans: `$$this.trans.${lang}` }]
}
}
}
}
]
}
}
}
}
}
]).toArray();
console.log(r);
我需要通过省略嵌套文档的某些字段来访问多嵌套子文档中的数据。架构如下所示,预期的输出也如下所示。由于不能在嵌套级别使用投影,所以我该怎么做?
下面给出的是具有嵌套条目的数据库模式,如图所示。
[
{
"_id": {
"$oid": "60e519db4e0f140328adc7c7"
},
"trans": {
"en": {
"name": "Graphics And Design",
"description": "Graphics And Design"
},
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"slug": "graphics-and-design",
"image": "",
"created_at": {
"$numberDouble": "1625627099104.0"
},
"subcategories": [
{
"trans": {
"en": {
"name": "LOGO DESIGN",
"description": "LOGO DESIGN"
},
"fr": {
"name": "LOGO DESIGN",
"description": "LOGO DESIGN"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "logo-design",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e61"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "3D logo",
"description": "3D logo design"
},
"fr": {
"name": "3D logo",
"description": "3D logo design"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e60"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
},
{
"trans": {
"en": {
"name": "BRAND STYLE GUIDES",
"description": "BRAND STYLE GUIDES"
},
"fr": {
"name": "BRAND STYLE GUIDES",
"description": "BRAND STYLE GUIDES"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "brand-style-guides",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e63"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "Brand style 1",
"description": "Brand style 1"
},
"fr": {
"name": "Brand style 1",
"description": "Brand style 1"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
},
{
"trans": {
"en": {
"name": "Brand style 2",
"description": "Brand style 2"
},
"fr": {
"name": "Brand style 2",
"description": "Brand style 2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
}
],
"updated_at": {
"$date": {
"$numberLong": "1625627153547"
}
}
},
//this is the another category
{
"_id": {
"$oid": "60e519db4e0f140328adc7c8"
},
"trans": {
"en": {
"name": "Graphics And Design2",
"description": "Graphics And Design2"
},
"fr": {
"name": "Graphics And Design2",
"description": "Graphics And Design2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"slug": "graphics-and-design2",
"image": "",
"created_at": {
"$numberDouble": "1625627099104.0"
},
"subcategories": [
{
"trans": {
"en": {
"name": "LOGO DESIGN2",
"description": "LOGO DESIGN2"
},
"fr": {
"name": "LOGO DESIGN2",
"description": "LOGO DESIGN2"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "logo-design2",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e61"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "3D logo2",
"description": "3D logo design2"
},
"fr": {
"name": "3D logo2",
"description": "3D logo design2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e60"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
},
{
"trans": {
"en": {
"name": "BRAND STYLE GUIDES2",
"description": "BRAND STYLE GUIDES2"
},
"fr": {
"name": "BRAND STYLE GUIDES2",
"description": "BRAND STYLE GUIDES2"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "brand-style-guides2",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e63"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "Brand style 12",
"description": "Brand style 12"
},
"fr": {
"name": "Brand style 12",
"description": "Brand style 12"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
},
{
"trans": {
"en": {
"name": "Brand style 22",
"description": "Brand style 22"
},
"fr": {
"name": "Brand style 22",
"description": "Brand style 22"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
}
],
"updated_at": {
"$date": {
"$numberLong": "1625627153547"
}
}
}
]
到目前为止我尝试过的代码:
const client = await Database.connect();
const lang = "en";
const r = await client
.collection("categories")
.aggregate([
{
$addFields: {
categories: {
$map: {
input: "$categories",
as: "c",
in: {
$mergeObjects: [
"$$this",
{
trans: `$$c.trans.${lang}`,
subcategories: {
$map: {
input: "$subcategories",
as: "s",
in: {
$mergeObjects: [
"$$this",
{
trans: `$$s.trans.${lang}`,
service_type: {
$map: {
input: "$$s.service_type",
as: "d",
in: {
$mergeObjects: [
"$$this",
{ trans: `$$d.trans.${lang}` },
],
},
},
},
},
],
},
},
},
},
],
},
},
},
},
},
])
.toArray();
console.log(r);
console.log(r)
的回复:
:: FieldPath field names may not start with '$'
预期输出:
[
{
"_id": ObjectId("60e519db4e0f140328adc7c7"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627099104.0"
},
"image": "",
"is_visible": true,
"slug": "graphics-and-design",
"subcategories": [
{
"_id": ObjectId("60e51a116678530e84ee2e61"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e60"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "service_type1",
"trans": {
"description": "service_type1",
"name": "service_type1"
}
}
],
"slug": "logo-design",
"trans": {
"description": "LOGO DESIGN",
"name": "LOGO DESIGN"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e63"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_BRAND STYLE GUIDES",
"name": "ServiceType1_BRAND STYLE GUIDES"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType2_BRAND STYLE GUIDES",
"name": "ServiceType2_BRAND STYLE GUIDES"
}
}
],
"slug": "brand-style-guides",
"trans": {
"description": "BRAND STYLE GUIDES",
"name": "BRAND STYLE GUIDES"
}
}
],
"trans": {
"description": "Graphics And Design",
"name": "Graphics And Design"
},
"updated_at": ISODate("2021-07-07T03:05:53.547Z")
},
{
"_id": ObjectId("60e519db4e0f140328adc7c8"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627099104.0"
},
"image": "",
"is_visible": true,
"slug": "graphics-and-design2",
"subcategories": [
{
"_id": ObjectId("60e51a116678530e84ee2e61"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e60"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_LOGO DESIGN2",
"name": "ServiceType1_LOGO DESIGN2"
}
}
],
"slug": "logo-design2",
"trans": {
"description": "LOGO DESIGN2",
"name": "LOGO DESIGN2"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e63"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_BRAND STYLE GUIDES2",
"name": "ServiceType1_BRAND STYLE GUIDES2"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType2_BRAND STYLE GUIDES2",
"name": "ServiceType2_BRAND STYLE GUIDES2"
}
}
],
"slug": "brand-style-guides2",
"trans": {
"description": "BRAND STYLE GUIDES2",
"name": "BRAND STYLE GUIDES2"
}
}
],
"trans": {
"description": "Graphics And Design2",
"name": "Graphics And Design2"
},
"updated_at": ISODate("2021-07-07T03:05:53.547Z")
}
]
请使用任何好的有效方法帮助解决此问题。
我没有得到你的尝试,你可以试试下面的方法,
$map
迭代subcategories
数组 的循环
$map
迭代service_type
数组 的循环
- select
trans
输入语言的对象 $mergeObjects
合并更新的trans
字段和service_type
数组 的当前对象
$mergeObjects
将更新的trans
和service_type
数组与subcategories
数组 的当前对象合并
var lang = "en";
const r = await client.collection("categories").aggregate([
{
$addFields: {
trans: "$trans.en",
subcategories: {
$map: {
input: "$subcategories",
as: "s",
in: {
$mergeObjects: [
"$$s",
{
trans: `$$s.trans.${lang}`,
service_type: {
$map: {
input: "$$s.service_type",
in: {
$mergeObjects: ["$$this", { trans: `$$this.trans.${lang}` }]
}
}
}
}
]
}
}
}
}
}
]).toArray();
console.log(r);