Meteor-Community-Packages / meteor-collection2

A Meteor package that extends Mongo.Collection to provide support for specifying a schema and then validating against that schema when inserting and updating.
https://packosphere.com/aldeed/collection2
MIT License
1.02k stars 109 forks source link

Update $pull an object from [Object]? #284

Open rtcwp07 opened 9 years ago

rtcwp07 commented 9 years ago

First of all I want to say thank you for providing these awesome packages, and I hope I'm asking this in the right place! Using Simple Schema and collection2, having trouble pulling one object from an array of objects. For a trivia game app, using $push to add new players is working fine, but for the life of me I can't figure out how to remove a particular player from the doc when they leave the game. Here's the schema:

GameRecords.attachSchema(
    new SimpleSchema({
    gamecode: {
      type: String
    },
    host: {
        type: String
    },
    players: {
      type: [Object],
        optional: true
    },
        "players.$.playerid": {
            type: String,
            defaultValue: null,
            optional: true
        },
        "players.$.playername": {
            type: String,
            defaultValue: null,
            optional: true
        },
        "players.$.score": {
            type: Number,
            defaultValue: null,
            optional: true
        },
    createdAt: {
        type: Date,
        autoValue: function() {
            if (this.isInsert) {
                return new Date();
            } else if (this.isUpsert) {
                return {$setOnInsert: new Date()};
            } else {
                this.unset();
            }
        }
    }
  })
);

I've tried every permutation of every schema variable and update method that I know is possible, including: 1) blackbox: true 2) getAutoValues: false 3) validate: false 4) $pull method, as:

GameRecords.update({_id: gamerecordId}, {$pull: {players: playerToPull}});

where playerToPull is the whole player object, right from the doc. 5) $set method, as:

GameRecords.update({_id: gamerecordId}, {$set: {players: newPlayers}});

where newPlayers is a splice of the original players array without the player object that I'm trying to remove.

Nothing I've tried has resulted in a successful update. Am I missing something obvious? Thanks for your help!

jupiterkenji commented 8 years ago

I'm experiencing the same behaviour, have you manage to get it resolved?

rtcwp07 commented 8 years ago

No, unfortunately I never did resolve that issue. Instead I had to redesign my application flow, which of course was a headache!

On Sat, May 7, 2016 at 1:00 AM, stewiegaribaldi notifications@github.com wrote:

I'm experiencing the same behaviour, have you manage to get it resolved?

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/aldeed/meteor-collection2/issues/284#issuecomment-217607971

jupiterkenji commented 8 years ago

Thank you for your reply rtcwp07, in my case it was my subdocument has auto value, so I need to do

eventid: {
  type: String,
  autoValue: function() {
    if (!this.isSet && this.operator !== "$pull") { // require pull check
      return Random.id();
    }
  },
}
rtcwp07 commented 8 years ago

Ah I see now! Great information, thanks.

On Wed, May 11, 2016 at 2:49 AM, stewiegaribaldi notifications@github.com wrote:

Thank you for your reply rtcwp07, in my case it was my subdocument has auto value, so I need to do

eventid: { type: String, autoValue: function() { if (!this.isSet && this.operator !== "$pull") { // require pull check return Random.id(); } }, }

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/aldeed/meteor-collection2/issues/284#issuecomment-218376463

stefanve commented 8 years ago

Have the same problem, can set and push but not pull Error: After filtering out keys not in the schema, your modifier is now empty

This finds the element: Orders.find({"handlingErrors.ticket.tempId": tempId}, {fields: {"handlingErrors.$.ticket": 1,_id: 0}}).fetch()

This updates it: Orders.update({_id: orderId, "handlingErrors.ticket.tempId": tempId}, {$set: {"handlingErrors.$.ticket.contactData.email": newEmail }}

This does NOT pull it: Orders.update({_id: orderId}, {$pull:{"handlingErrors.$.ticket.tempId": tempId}})

stefanve commented 8 years ago

Ooops, ignore my previous comment. I got the query wrong, this works: Orders.update({_id: orderId}, {$pull:{"handlingErrors": {"ticket.tempId": tempId}}})

it needs to know what to pull...

aldeed commented 6 years ago

Closing old issues. Please comment if this is still an issue and should be reopened.

ChrisOelmueller commented 6 years ago

@aldeed
I'm fairly certain this is still happening. Could you take a look at the following dummy sample and confirm that the expected outcome is "some things are present" while the actual result is empty things arrays all over the place?

I prepared it in Meteor (1.6.0) but probably similar results can be observed using just npm packages.

import { Mongo } from 'meteor/mongo';
import SimpleSchema from 'simpl-schema';

s = new SimpleSchema({
    'things': {
        type: Array,
    },
    'things.$': {
        type: Object,
    },
    'things.$.name': {
        type: String,
    },
    'things.$.valid': {
        type: Boolean,
        optional: true,
        defaultValue: true,
    },
});

Hello = new Mongo.Collection('absolutelyFilledWithThings');
Hello.attachSchema(s);

Hello.insert({'things': [{
    'name': 'yep',
    'valid': true, // Note: The schema defaultValue for this property is also `true`
}, {
    'name': 'sure',
    'valid': true,
},
]});

Hello.update(
    {},
    {$pull: {'things': {'valid': 'cute-kitten'}}}, // Note: This shouldn't match anything
    {'multi': true}
); // Expected outcome: No changes, all inserted entries have a two-element `things` array
console.dir(Hello.find().fetch(), {'depth': 3});
// After the update is executed, however, all DB entries will have `things: []` (empty array!)
aldeed commented 6 years ago

Haven't had a chance to look yet, but I'll reopen for now

thumptech commented 5 years ago

I can confirm I am having this problem and struggling to find a workaround.