我目前有一个产品架构,该架构具有一个包含数量不同的对象的属性数组。一个对象看起来像这样:
[{属性:'颜色',值:'黑色'},{属性:'长度',值:'1英寸'}]
每种产品都有随机数量的属性。问题是我无法查找产品并通过其标识符获取其属性。
下面是产品架构。
const mongoose = require('mongoose');
let product = new mongoose.Schema({
id: { type: mongoose.Schema.Types.ObjectId },
created_at: { type: Date, default: new Date()},
language: { type: String, required: true },
category: { type: String },
articlenumber: { type: String },
name: { type: String },
properties: { type: [{}] }
});
module.exports = product;
我的属性集合中也有一个带有标识符的属性架构。
const mongoose = require('mongoose');
let property = new mongoose.Schema({
id: { type: mongoose.Schema.Types.ObjectId },
categoryPropertyId: { type: String },
language: { type: String },
name: { type: String, unique: true }
});
module.exports = property;
{id:ObjectID,categoryPropertyId:“ 317”,语言:“ US”,名称:“ Color”}
我想获得一个产品,并根据其名称和语言加入,并获得categoryPropertyId。
猫鼬有可能吗?我可以使用javascript循环来做到这一点,但希望加入类似的内容。
我已经看过$ lookup并进行填充,但是我对猫鼬不是那么熟练。任何帮助表示赞赏!
产品
{
_id: 5b3f18d93098293c4ab0ca4a,
created_at: ‘2018-07-06 09:22:45.377’,
language: ‘US’,
category: ‘Phones’,
articlenumber: ‘6700’,
name: ‘Sony Phone’
properties: [
{
property: ‘Version’,
helptext: ‘’,
value: ’8.0’
},
{
property: ‘Operating System’,
helptext: ‘’,
value: ‘Android’
}]
}
属性数据集
[
{
id: ‘5b3603a56a14e1072ba6f4ef’,
categoryPropertyId: ’429’,
language: ‘US’,
name: ‘Android’
},
{
id: ‘5b3603a56a14e1072ba6f4ef’,
categoryPropertyId: ’977’,
language: ‘US’,
name: ‘Version’
},
{
id: ‘5b3603a56a14e1072ba6f4ef’,
categoryPropertyId: ’1033’,
language: ‘US’,
name: ‘Weight’
}
]
预期产量
{
_id: 5b3f18d93098293c4ab0ca4a,
created_at: ‘2018-07-06 09:22:45.377’,
language: ‘US’,
category: ‘Phones’,
articlenumber: ‘6700’,
name: ‘Sony Phone’
properties: [
{
property: ‘Version’,
helptext: ‘’,
value: ’8.0’,
categoryPropertyId: ’977’
},
{
property: ‘Operating System’,
helptext: ‘’,
value: ‘Android’,
categoryPropertyId: ’429’
}
]
}
答案 0 :(得分:1)
尝试以下代码:
db.getCollection("products").aggregate(
// Pipeline
[
// Stage 1
{
$unwind: {
path : "$properties",
includeArrayIndex : "arrayIndex", // optional
preserveNullAndEmptyArrays : false // optional
}
},
// Stage 2
{
$lookup: // Equality Match
{
from: "properties",
localField: "properties.value",
foreignField: "name",
as: "newData"
}
},
// Stage 3
{
$unwind: {
path : "$newData",
includeArrayIndex : "arrayIndex", // optional
preserveNullAndEmptyArrays : false // optional
}
},
// Stage 4
{
$project: {
"language": "$language",
"category" : "$category",
"articlenumber" : "$articlenumber",
"name" : "$name",
"properties": {
"property":"$properties.property",
"helptext": "$properties.helptext",
"value":"$properties.value",
"categoryPropertyId":"$newData.categoryPropertyId"
}
}
},
// Stage 5
{
$group: {
"_id": "$_id",
"properties": { "$push": "$properties" },
"language": { "$first": "$language" },
"category": { "$first": "$category" },
"articlenumber": { "$first": "$articlenumber" },
"name": { "$first": "$name" }
}
},
]
);
希望这可以解决您的查询。
答案 1 :(得分:1)
您可以尝试以下汇总
基本上,您需要先$unwind
"properties"
数组才能与外来的“名称”相匹配... let
允许您
保留从根文档(产品)到内部文档(属性)的字段,最后使用$group
您可以将拆分的“属性”再次回滚到“属性”数组。
如果您有mongodb 3.6版
db.product.aggregate([
{ "$unwind": "$properties" },
{ "$lookup": {
"from": Properties.collection.name,
"let": { "property": "$properties.property" },
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$name", "$$property" ] } } },
{ "$project": { "categoryPropertyId": 1 }}
],
"as": "properties.prop"
}},
{ "$unwind": "$properties.prop" },
{ "$addFields": {
"properties.categoryPropertyId": "$properties.prop.categoryPropertyId"
}},
{ "$project": { "properties.prop": 0 }},
{ "$group": {
"_id": "$_id",
"created_at": { "$first": "$created_at" },
"language": { "$first": "$language" },
"category": { "$first": "$category" },
"articlenumber": { "$first": "$articlenumber" },
"name": { "$first": "$name" },
"properties": { "$push": "$properties" }
}}
])
,如果您的mongodb版本低于3.6
db.product.aggregate([
{ "$unwind": "$properties" },
{ "$lookup": {
"from": Properties.collection.name,
"localField": "properties.property",
"foreignField": "name",
"as": "properties.prop"
}},
{ "$unwind": "$properties.prop" },
{ "$addFields": {
"properties.categoryPropertyId": "$properties.prop.categoryPropertyId"
}},
{ "$project": { "properties.prop": 0 }},
{ "$group": {
"_id": "$_id",
"created_at": { "$first": "$created_at" },
"language": { "$first": "$language" },
"category": { "$first": "$category" },
"articlenumber": { "$first": "$articlenumber" },
"name": { "$first": "$name" },
"properties": { "$push": "$properties" }
}}
])