首页 > 解决方案 > MongoDB/Mongoose 基于名称加入

问题描述

我目前有一个产品模式,它有一个包含不同数量对象的属性数组。一个对象如下所示:

[{ 属性:'颜色',值:'黑色'},{ 属性:'长度',值:'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’
        }
    ]
}

标签: node.jsmongodbmongoose

解决方案


试试这个代码:

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" }
                }
        },

    ]

);

希望这能解决您的疑问。


推荐阅读