简体   繁体   中英

MongoDB get documents with at least one not empty array

My schema:

    db.Interactives = mongoose.model(
        'Interactives',
        new Schema({
            url: String,
            forms: Array,
            inputs: Array,
            textareas: Array,
        })
    );

I want to find all documents where at least one array isnt empty, so I tried:

    await db.Interactives.find({
            $elemMatch: {
                forms: { $ne: [] },
                inputs: { $ne: [] },
                textarea: { $ne: [] },
            },
        })
            .select('-_id -__v')
            .exec()

How can I achieve this?

The issue with your code is that it is trying make sure no arrays are empty. The other issue is that $elemMatch searches elements of an array for a value. You don't want to do that, you want to compare the array with a blank array. The only change you have to make is replace $elemMatch with $or and add brackets like so

    await db.Interactives.find({
            $or: [
                {forms: { $ne: [] }},
                {inputs: { $ne: [] }},
                {textarea: { $ne: [] }},
            ]
        })
            .select('-_id -__v')
            .exec()

What you missed is $or in your query.

Also it can be done in many ways. Suppose this is your data set.

[
  {"Id_Cust": "4145","firstName": "Albade","language": ["English,Nepali"],"degree": []},
  {"Id_Cust": "5296","firstName": "Rafael","language": [],"degree": ["Bachelor,Masters"]},
  {"Id_Cust": "6192","firstName": "Abdul","language": [],"degree": []}
]

Now, you can do:

db.collection.find({
  $or: [
    {language: {$exists: true,$not: {$size: 0}}},
    {degree: {$exists: true,$not: {$size: 0}}}
  ]
})

If your fields in array are optional fields use $exists otherwise you can exclude it.

Alternative I

db.collection.find({
  $or: [
    {language: {$ne: []}},
    {degree: {$ne: []}}
  ]
})

If your fields in array are optional fields use $exists just like in the above query.

Alternative II

db.collection.find({
  $or: [
    {language: {$gt: []}},
    { degree: {$gt: []}}
  ]
})

If your fields in array are optional fields use $exists just like in the very first query.

All methods gives same output :

[
  {
    "Id_Cust": "4145",
    "_id": ObjectId("5a934e000102030405000000"),
    "degree": [],
    "firstName": "Albade",
    "language": [
      "English,Nepali"
    ]
  },
  {
    "Id_Cust": "5296",
    "_id": ObjectId("5a934e000102030405000001"),
    "degree": [
      "Bachelor,Masters"
    ],
    "firstName": "Rafael",
    "language": []
  }
]

So, you can do it in any way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM