0

I am trying to remove all products from the products array where the product has no rates. In my queries below I tried to check the length of the rates array, but none of them seem to work. Any help is appreciated.

Thanks in advance

var ProductRateSchema = new Schema({
    product: {
        type: Schema.ObjectId,
        ref: 'products'
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    },
    rates: [{
        type: Schema.ObjectId,
        ref: 'rates'
    }]
});

var InventorySchema = new Schema({
    name: {
        type: String,
        default: '',
        required: 'Please enter in a name',
        trim: true
    },
    created: {
        type: Date,
        default: Date.now
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    },
    products: [productRateSchema]

});


var inventoryId = req.body.inventoryId;
var productId = req.body.productId;


// none of these queries work

db.inventory.findOneAndUpdate({ '_id': inventoryId,
 {$pull: {'products': { product: productId, 'rates': { $eq:[] }}}}, function (err, result) {

 });

db.inventory.findOneAndUpdate({ '_id': inventoryId,
 {$pull: {'products': { product: productId, 'rates': {$size: {$lt: 1}}}}}, function (err, result) {

 });


db.inventory.findOneAndUpdate({ '_id': inventoryId,
 {$pull: {'products': { product: productId, 'rates': null }}}, function (err, result) {

 });
Blakes Seven
  • 44,166
  • 12
  • 104
  • 116
noobie
  • 1,894
  • 5
  • 27
  • 57
  • What query? Nothing here but schema definition. – Blakes Seven Mar 26 '16 at 23:34
  • the queries are there, there are no scrollbars, but there is more code if you scroll – noobie Mar 27 '16 at 00:51
  • Missed them. Doesn't really matter as there are good reasons why all attempts fail. Mostly for invalid syntax since there are seperate "query" and "update" arguments that you missed in every case. Answered anyway. – Blakes Seven Mar 27 '16 at 01:02

1 Answers1

1

Don't know what you tried since it is simply not included in your question, but the best way to check for an empty array is to basically look where the 0 index does not match $exists:

Inventory.update(
    { "products.rates.0": { "$exists": false } },
    { 
        "$pull": {
            "products": { "rates.0": { "$exists": false } }
        }
    },
    { "multi": true },
    function(err,numAffected) {

    }
)

The "query" portion of the .update() statement is making sure that we only even attempt to touch documents which have an empty array in "products.rates". That isn't required, but it does avoid testing the following "update" statement condition on documents where that condition is not true for any array element, and thus makes things a bit faster.

The actual "update" portion applies $pull on the "products" array to remove any of those items where the "inner" "rates" is an empty array. So the "path" within the $pull is actually looking inside the "products" content anyway, so it is relative to that and not to the whole document.

Naturally $pull will remove all elements that match in a single operation. The "multi" is only needed when you really want to update more than one document with the statement

Blakes Seven
  • 44,166
  • 12
  • 104
  • 116