如何对数组中子文档中字段的值求和?

How to sum the values from a field in subdocuments from an array?

如何从提供的任何关键字中仅投射在每个文档中找到的词?文件结构如下:

{
    _id: 24752893,
    dictionary: [
        {
            word: 'word1',
            count: 2,
        },
        {   
            word: 'word2',
            count: 5,
        },
        {
            word: 'word4',
            count: 1,
        },
        ....
    ]
},
{
    _id: 6786765789,
    dictionary: [
        {
            word: 'word4',
            count: 3,
        },
        {
            word: 'word2',
            count: 6,
        },
        {
            word: 'word3',
            count: 3,
        },
        {
            word: 'word5',
            count: 1,
        },
        ....
    ]
},
........
{
    _id: 76675567,
    dictionary: [
        {
            word: 'word1',
            count: 7,
        },
        {
            word: 'word3',
            count: 2,
        },
        ....
    ]
}

如果给出了像 ['word2'、'word3'] 这样的关键字列表,只要关键字中的任何一个都应该检索文档在其中找到关键字列表。我已经编写了这个聚合管道来获取必要的文件:

client.database.collection.aggregate([
    {
    '$project': {
        '_id': 1,
        'dictionary': {
            '$filter': {
                'input': '$dictionary',
                'as': 'words',
                'cond': {
                    '$in': [
                        '$$words.word', keywords
                    ]
                }
            }
        },
    }
},
{
    '$match': {
        'dictionary': {
            '$ne': []
        }
    }
},
,
{
    '$unwind': '$dictionary'
},
{
    '$group': {
        '_id': '$_id',
        'score': {
            '$sum': '$dictionary.count'
        }
    }
}
])

我想做的不是投影整个词典,而是只想投影每个文档的匹配词及其计数。当然,我希望每个文档的字典都在单独的投影文档中。有什么办法吗?

使用 $filter 过滤数组,试试这个:

let keywords = ['word2', 'word3']

db.collection.aggregate([
    {
        $project: {
            _id: 0,
            dictionary: {
                $filter: {
                    input: "$dictionary",
                    as: "word",
                    cond: {
                        $in: ["$$word.word", keywords]
                    }
                }
            }
        }
    },
    {
        $match: {
            $expr: {
                $gt: [{ $size: "$dictionary" }, 0]
            }
        }
    }
]);

输出:

/* 1 */
{
    "dictionary" : [
        {
            "word" : "word2",
            "count" : 5
        }
    ]
},

/* 2 */
{
    "dictionary" : [
        {
            "word" : "word2",
            "count" : 6
        },
        {
            "word" : "word3",
            "count" : 3
        }
    ]
},

/* 3 */
{
    "dictionary" : [
        {
            "word" : "word3",
            "count" : 2
        }
    ]
}