过滤掉空元素文档

Filter out empty element documents

我们有一家店铺collection如下。
我们需要 return 所有没有批次的唯一 'shop' 为空([])。

由于这是聚合中的一个阶段 - 它无法利用索引。
所以我们需要找到最有效的方法来完成上述操作。

{
    "_id": ObjectId("xxxxxx"),
    "shop": "Q4",
    "batch": ["5647"],
},
{
    "_id": ObjectId("xxxxxx"),
    "shop": "Q4",
    "batch": ["2314", "0121"],
},
{
    "_id": ObjectId("xxxxxx"),
    "shop": "Q1",
    "batch": ["5647"],
},
{
    "_id": ObjectId("xxxxxx"),
    "shop": "Q1",
    "batch": [],
}

预期结果:第 4 季度

这里是聚合查询,

输入:

{
    "_id" : ObjectId("5e33c96b08591b1809677543"),
    "shop" : "Q5",
    "batch" : [
        "5857",
        "5837"
    ]
},

{
    "_id" : ObjectId("5e33c95a08591b1809677542"),
    "shop" : "Q5",
    "batch" : [
        "5657"
    ]
},

{
    "_id" : ObjectId("5e33c93008591b1809677540"),
    "shop" : "Q1",
    "batch" : [
        "5648",
        "5628"
    ]
},

{
    "_id" : ObjectId("5e33c2fe08591b180967753f"),
    "shop" : "Q1",
    "batch" : [ ]
},

{
    "_id" : ObjectId("5e33c2fe08591b180967753e"),
    "shop" : "Q1",
    "batch" : [
        "5647"
    ]
},

{
    "_id" : ObjectId("5e33c2fe08591b180967753d"),
    "shop" : "Q4",
    "batch" : [
        "2314",
        "0121"
    ]
},

{
    "_id" : ObjectId("5e33c2fe08591b180967753c"),
    "shop" : "Q4",
    "batch" : [
        "5647"
    ]
}

查询:

const query = [
    {
        $group: {
            _id: "$shop",
            batch: { $push: "$batch" }
        }
    },
    {
        $match: {
            'batch': { $ne: [] }
        }
    },
    {
        $project: {
            _id: 1
        }
    }

];

db.trades.aggregate(query)

结果:

{
    "_id" : "Q5"
},     
{
    "_id" : "Q4"
}

试试这个:

db.shop.aggregate([{
    $group: {
        _id: '', shop: { $addToSet: '$shop' },
        emptyBatchShops: { $push: { $cond: [{ $eq: ['$batch', []] }, '$shop', null] } }
    }
}, { $project: { _id :0, uniques: { $setDifference: ["$shop", "$emptyBatchShops"] } } }])

收集数据:

/* 1 */
{
    "_id" : ObjectId("5e33c4daa855df1587760621"),
    "shop" : "Q4",
    "batch" : [ 
        "5647"
    ]
}

/* 2 */
{
    "_id" : ObjectId("5e33c4daa855df1587760622"),
    "shop" : "Q4",
    "batch" : [ 
        "2314", 
        "0121"
    ]
}

/* 3 */
{
    "_id" : ObjectId("5e33c4daa855df1587760623"),
    "shop" : "Q1",
    "batch" : [ 
        "5647"
    ]
}

/* 4 */
{
    "_id" : ObjectId("5e33c4daa855df1587760624"),
    "shop" : "Q1",
    "batch" : []
}

/* 5 */
{
    "_id" : ObjectId("5e33c8fca855df1587760625"),
    "shop" : "Q5",
    "batch" : [ 
        "5647"
    ]
}

/* 6 */
{
    "_id" : ObjectId("5e33c8fca855df1587760626"),
    "shop" : "Q5",
    "batch" : [ 
        "5647"
    ]
}

/* 7 */
{
    "_id" : ObjectId("5e33c907a855df1587760627"),
    "shop" : "Q6",
    "batch" : []
}

/* 8 */
{
    "_id" : ObjectId("5e33c907a855df1587760628"),
    "shop" : "Q6",
    "batch" : [ 
        "5647"
    ]
}

/* 9 */
{
    "_id" : ObjectId("5e33c90ea855df1587760629"),
    "shop" : "Q7",
    "batch" : []
}

/* 10 */
{
    "_id" : ObjectId("5e33c90ea855df158776062a"),
    "shop" : "Q8",
    "batch" : [ 
        "5647"
    ]
}

结果:

{
    "uniques" : [ 
        "Q5", 
        "Q4", 
        "Q8"
    ]
}

我试过这个聚合:

db.shops.aggregate( [
  { 
      $group: { 
          _id: "$shop", 
          hasEmptyBatches: { $addToSet: { $cond: [ {$eq: [ { $size: "$batch" }, 0 ] }, true, false ] } } 
      } 
  },
  { 
      $match: { hasEmptyBatches: { $ne: true } } 
  }
] )