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 108 forks source link

Using the all positional operator $[] in nested arrays causes an error #407

Closed Shelagh-Lewins closed 3 years ago

Shelagh-Lewins commented 4 years ago

Hi, I don't know if this is a bug in simple schema or if I'm doing something wrong.

I have a nested array like this:

myGrid = [
[1,0,2,3],
[2,2,0,1].
]

My schema is like this:

const MyCollectionSchema = new SimpleSchema({
'myGrid': {
    'type': Array,
},
'myGrid.$': {
    'type': Array,
},
'myGrid.$.$': {
    'type': SimpleSchema.Integer,
},
});

And I am updating the array like this:

const update = {};
update.$push = {
    'myGrid.$[]': {
        '$each': [3,2,3],
        '$position': 2,
    },
};

MyCollection.update({ _id }, update);

This inserts the new values [3,2,3] into each child array at position 2, as per the docs. (I'm using this form because I'm performing multiple updates in one operation, but I've left out the other updates from this example.)

When I run the code I see this error:

Exception ...{ Error: myGrid.$[] is not allowed by the schema (myGrid.$[])

If I bypass Collection2 like this, the operation succeeds:

MyCollection.update({ _id }, update, { 'bypassCollection2': true });

Is there a way to make this operation pass the schema? Or is it a bug? Thank you.

harryadel commented 4 years ago

Again, it's related to simple-schema. There's a way to make it pass which is to remove the [] in myGrid.$[].

The error happens at this line. Basically it searches for key named myGrid.$[] but the key is named myGrid.$ in our case. I guess I need to dig deeper into simple-schema to find out if it supports positional operator in general.

I'm wondering though how can you use the positional operator when you're coupling it with position and each?? According to the documentation using positional operator set the value for all values.

db.collection.update(
   { myArray: [ 5, 8 ] },
   { $set: { "myArray.$[]": 10 } },
   { upsert: true }
)

So what's the use for $each and $position in your example here?

StorytellerCZ commented 3 years ago

Since this is primarily an issue with simpl-schema I'm going to close this issue. If you feel that it is something that we can deal with here or the situation changes, please re-open this issue.

harryadel commented 3 years ago

While I've not read too deep into it but this PR may alleviate the problem you're facing guys.

derwaldgeist commented 2 years ago

Just came across this problem. Being able to adress multiple array items is actually quite important. Has this been fixed in simpl-schema in the meantime?