Mongodb Mongo-返回存在一个值但不存在另一个值的项

Mongodb Mongo-返回存在一个值但不存在另一个值的项,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一个文档集合,这些文档表示在不同地区可用的产品。某些产品仅在某些地区可用。如果一个产品没有针对某一特定区域列出,那么它就不适用于该区域 下面是一个很小的例子,只有相关的部分: { "locale": "US", "productId": "123" } { "locale": "CA", "productId": "123" } { "locale": "FR", "productId": "123" } { "locale": "US", "productId": "456" } { "l

我有一个文档集合,这些文档表示在不同地区可用的产品。某些产品仅在某些地区可用。如果一个产品没有针对某一特定区域列出,那么它就不适用于该区域

下面是一个很小的例子,只有相关的部分:

{ "locale": "US", "productId": "123" }
{ "locale": "CA", "productId": "123" }
{ "locale": "FR", "productId": "123" }
{ "locale": "US", "productId": "456" }
{ "locale": "FR", "productId": "456" }
我想查询所有在美国可用的productId,但在CA中不可用。在本例中,这将是productId 456


如果我在SQL中这样做,我会将表连接到它自己,并以这种方式找到答案。但我不知道如何在Mongo中处理这种查询。做这类事情最合适的方法是什么?

您可以使用聚合管道:

db.products.aggregate([ 
  { $group: { _id: "$productId", locales: { $push: "$locale" } } },
  { $match: { locales: "US", locales: {$nin: ["CA"] } } },
  { $project: { _id: 0, productId: "$_id" } }
])
详情:

  • 按id对产品进行分组,并将所有产品区域设置推送到阵列中
  • 选择那些具有US语言环境但没有CA语言环境的文档
  • 项目结果以仅获取productId值
  • 输出:

    { "productId" : "456" }
    

    请注意,如果要在匹配阶段后进行分组,则可以在单个阵列中获取所有产品ID:

    { $group: { _id: 1, productIds: { $push: "$_id" } } }
    

    根据上述问题中的描述,请尝试在MongoDB shell中执行以下聚合查询

        db.collection.aggregate(
    
        // Pipeline
        [
            // Stage 1
            {
                $group: {
                 _id:{productId:'$productId'},
                 locale:{$addToSet:'$locale'}
                }
            },
    
            // Stage 2
            {
                $match: {
                   locale:{$in:['US'],$nin:['CA']}
                }
            },
    
        ]
    );
    
    上述聚合查询在管道中执行以下聚合阶段

    • $group operator根据productId和 使用将与productId关联的区域设置值推送到数组中 $addToSet运算符

    • $match operator筛选只有美国语言环境的文档
      从区域设置数组中排除具有CA区域设置的文档
      在分组阶段生成的值


    也许还有一种方法可以使用$lookup,使用
    locale
    作为localField和foreignField,你觉得怎么样?@alfredpacino我认为我们不需要在这里查找,因为OP要求产品ID-分组非常适合此任务