Mongodb find()只包含非空数组

Ash*_*rke 2 javascript mongoose mongodb node.js aggregation-framework

我想用find查询实现的只是包含"someArray",如果它的内部数组不为空.例如下面的JSON:

{
  "document": "some document",
  "someArray": [
    {
      "innerArray": [
        "not empty"
      ]
    },
    {
      "innerArray": [
        [] //empty
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

会回来这个:

{
  "document": "some document",
  "someArray": [
    {
      "innerArray": [
        "not empty"
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我正在使用以下查找:

Visit.find({'someArray.innerArray.0': {$exists: true}}, function(err, data){});
Run Code Online (Sandbox Code Playgroud)

但是,这会返回所有数据.

也尝试过:

Visit.find({}, {'someArray.innerArray': {$gt: 0}}, function(err, data) {});
Run Code Online (Sandbox Code Playgroud)

但这没有任何回报

关于如何处理这个的任何想法?

干杯

Nei*_*unn 8

检查非空数组的一般情况是检查"first"元素是否确实存在.对于单个匹配,您可以使用位置$运算符进行投影:

Vist.find(
    { "someArray.innerArray.0": { "$exists": true } },
    { "document": 1,"someArray.$": 1},
    function(err,data) {

    }
);
Run Code Online (Sandbox Code Playgroud)

如果您需要多个匹配或者嵌套的数组比这更深,那么聚合框架就是您需要处理更难的投影和/或"过滤"多个匹配的数组结果:

Visit.aggregate(
    [
        // Match documents that "contain" the match
        { "$match": {
            "someArray.innerArray.0": { "$exists": true }
        }},

        // Unwind the array documents
        { "$unwind": "$someArray" },

        // Match the array documents
        { "$match": {
            "someArray.innerArray.0": { "$exists": true }
        }},

        // Group back to form
        { "$group": {
            "_id": "$_id",
            "document": { "$first": "$document" },
            "someArray": { "$push": "$someArray" }
        }}

    ],function(err,data) {


    }
)
Run Code Online (Sandbox Code Playgroud)

值得注意的是,你在调用这个"空"但事实上并非如此,因为它实际上包含另一个空数组.您可能不希望使用真实数据,但如果您有,那么您需要像这样过滤:

Visit.aggregate(
    [
        { "$match": {
            "someArray": { "$elemMatch": { "innerArray.0": { "$ne": [] } } }
        }},
        { "$unwind": "$someArray" },
        { "$match": {
            "someArray.innerArray.0": { "$ne": [] }
        }},
        { "$group": {
            "_id": "$_id",
            "document": { "$first": "$document" },
            "someArray": { "$push": "$someArray" }
        }}
     ],function(err,data) {


     }
);
Run Code Online (Sandbox Code Playgroud)