Simpleschema gives error when Mongo update array of objects: Why does update a field in in array over all documents not work?

Hi

do you maybe see whats wrong with this simple query?
I already looked here

Meteor.methods({
    resetLoggedInUser() {
        console.log("Method resetLoggedInUsers");
        //https://docs.mongodb.com/manual/tutorial/update-documents/#update-multiple-documents
        Customers.update({}, {
            $set: { "users.$.currentlyLoggedIn": false }
        });

my Customer schema


export const Customers = new Mongo.Collection('customers');

Customers.attachSchema(new SimpleSchema({
    name: {
        type: String,
        label: "Name of your customer"
    },
    checked: {
        type: Boolean,
        label: "Selected for the generation?",
        optional: true
    },
    createdAt: {
        type: Date,
        label: "Date created",
        optional: true
    },
    createdBy: {
        type: Object,
        label: "Date created",
        optional: true
    },
    users: {
        type: Array,
        optional: true
    },
    "users.$": {
        type: Object
    },
    "users.$.name": {
        type: String
    },
    "users.$.group": {
        type: String
    },
    "users.$.currentlyLoggedIn": {
        type: Boolean
    },
    "users.$.country": {
        type: String
    }
}));

the error I get:

Thank you

I’m not sure if that’s exactly your schema, or if you’re just normalizing your schema with “$” for the purposes of showing us. But if your field names really do include ".$"…

Do not use ".$" in your field names!!! This is reserved for MongoDB and is used to refer to elements in an array field which were matched in the query selector.

Thank you.

That is the Validation schema for the collection. GitHub - longshotlabs/meteor-simple-schema: Only getting critical fixes. Please use the NPM package instead

The field in mongo looks like
`users.currentlyLoggedin’

Mm, maybe this works http://maz-dev.cc/update-on-mongo-subdocuments/

There is no type: Array (rules), do you maybe want this:

users: {
  type: [Object],
  optional: true
},

@hoser23331, Simple Schema hasn’t got any rule called Array, so use [Object] instead as @mitjajez rightfully suggested.

Funny, I see what you mean in simpleschema. But I generated my code with this tool, so is that a bug?
http://autoform.meteorapp.com/quickform

Btw, it did not solve the issue, I still get

MongoError: The positional operator did not find the match needed from the query. Unexpanded update: users.$.currentlyLoggedIn

I suspect the issue comes from simpleschema. It tries to validate my update. That is ok. But I want to update all documents, So I leave the query param empty {}.

I also tried this solution (did not work)

 Customers.update({
        }, {
            $set: {
                'users.$': {
                    'currentlyLoggedIn': false
                }
            }
        });
        // Customers.update({}, {

I think the issue is, is that the update statement removes the whole object and therefore the validation fails. I just want to say: for all my document for all users set logged in to false.

I think you’re correct, it removes all just what you update: {} = all.
If you want to update specific field vallue/document, you should specify it, try:

Customers.update(
  { users: "Who" },
  { $set: "users.$.currentlyLoggedIn": false }
)
1 Like

Ok thank you. But I want to update all users. So I don’t know the WHO, therefore I keep the query empty…Can this be done?

yeah @hoser23331 … just use {} instead of {user: "Who"} in the query. so it’s going to be like this:

Customers.update({}, {$set: "users.$.currentlyLoggedIn": false })
1 Like

Hi,
@snamoah , thanks but that does not work as mentoined above.

I now have this working, but please tell me we can do it smarter in meteor…

Meteor.methods({
    resetLoggedInUser() {
        console.log("Method resetLoggedInUsers");

        Customers.find()
            .forEach(function(customer) {
                var updatedUsers = _.map(customer.users, function(user) {
                    user.currentlyLoggedIn = false;
                    return user;
                })

                Customers.update(customer._id, {
                    $set: { users: updatedUsers },
                });
            })

That’s strange @hoser23331 because according to the mongodb doc, that’s how to get it to work.

Aah… actually I think I know what the problem is. It was my mistake. I mixed coffeescript with the javascript. Here’s the correct code:

Customers.update({}, {$set: {"users.$.currentlyLoggedIn": false}});

I hope it helps

Thank you! because I hate my correct code, way to long!

1 Like