我所有的记录都有一个名为“图片”的字段。这个字段是一个字符串数组。

我现在想要最新的10条记录,其中这个数组不是空的。

我搜索了一下,但奇怪的是,我并没有在这方面找到太多。 我已经阅读了$where选项,但我想知道本机函数有多慢,如果有更好的解决方案。

即便如此,这也行不通:

ME.find({$where: 'this.pictures.length > 0'}).sort('-created').limit(10).execFind()

返回什么。离开这。没有长度位的图片也可以,但当然,它也会返回空记录。


当前回答

您可以使用以下任何一种方法来实现此目的。 对于不包含所请求键的对象,两者都不会返回结果:

db.video.find({pictures: {$exists: true, $gt: {$size: 0}}})
db.video.find({comments: {$exists: true, $not: {$size: 0}}})

其他回答

从2.6版本开始,另一种方法是将字段与空数组进行比较:

ME.find({pictures: {$gt: []}})

在外壳中进行测试:

> db.ME.insert([
{pictures: [1,2,3]},
{pictures: []},
{pictures: ['']},
{pictures: [0]},
{pictures: 1},
{foobar: 1}
])

> db.ME.find({pictures: {$gt: []}})
{ "_id": ObjectId("54d4d9ff96340090b6c1c4a7"), "pictures": [ 1, 2, 3 ] }
{ "_id": ObjectId("54d4d9ff96340090b6c1c4a9"), "pictures": [ "" ] }
{ "_id": ObjectId("54d4d9ff96340090b6c1c4aa"), "pictures": [ 0 ] }

因此,它正确地包含了其中pictures至少有一个数组元素的文档,并排除了其中pictures为空数组、不是数组或缺失的文档。

ME.find({pictures: {$exists: true}}) 

就这么简单,这招对我很管用。

这也是可行的:

db.getCollection('collectionName').find({'arrayName': {$elemMatch:{}}})

如果你也有没有密钥的文档,你可以使用:

ME.find({ pictures: { $exists: true, $not: {$size: 0} } })

MongoDB不使用索引,如果涉及$size,所以这里有一个更好的解决方案:

ME.find({ pictures: { $exists: true, $ne: [] } })

如果你的属性可以有无效值(如null boolean或其他),那么你可以添加一个额外的检查使用$types建议在这个答案:

与芒果>= 3.2:

ME.find({ pictures: { $exists: true, $type: 'array', $ne: [] } })

与mongo < 3.2:

ME.find({ pictures: { $exists: true, $type: 4, $ne: [] } })

从MongoDB 2.6版本开始,你可以与操作符$gt进行比较,但这可能会导致意想不到的结果(你可以在这个答案中找到详细的解释):

ME.find({ pictures: { $gt: [] } })

你也可以使用帮手方法Exists代替Mongo操作符$ Exists

ME.find()
    .exists('pictures')
    .where('pictures').ne([])
    .sort('-created')
    .limit(10)
    .exec(function(err, results){
        ...
    });