Skip to content

minimongo use of undefined doesn't match mongo shell #1646

Closed
@datacarl

Description

@datacarl
Contributor

Mini-mongo doesn't treat undefined in a $in lookup the same way as the server does. On the server it matches both null and undefined, but on the client it doesnt match any of them.

  Collection.insert({name: [null]});
  Collection.insert({name: [undefined]});
  Collection.insert({name: ['test']});

//server
console.log(Collection.find({name : {$in : [undefined]}}).count()); // -> 2

//client
console.log(Collection.find({name : {$in : [undefined]}}).count()); // -> 0

Activity

glasser

glasser commented on Dec 3, 2013

@glasser
Contributor

The use of undefined in Mongo is pretty inconsistent. The BSON spec (BSON is the object format developed for Mongo's wire protocol) says that undefined is deprecated, and in fact the Node Mongo driver doesn't know how to read or write undefined.

So when you insert things with undefined via Meteor (or anything using the Node Mongo driver), they get converted to null. Similarly, when the Meteor server executes a query with undefined it gets converted to null by the Node Mongo driver. On the other hand, on the client we don't serialize the query to BSON so it tries to actually match undefined against the nulls and gets nothing.

In general we do want minimongo's behavior to match Mongo's. Mongo's behavior with undefined in queries is pretty inconsistent, though! If I use the mongo shell (which, while JavaScript, does not use the Node mongo driver and is capable of differentiating undefined from null) it says:

> db.x.find({name: undefined})
error: { "$err" : "can't have undefined in a query expression", "code" : 13629 }

even though when you put it in a $in it "works".

BTW: if you insert something with undefined in the Mongo shell, the undefined does get into the database, but the Mongo shell still prints it as null. You can see that here:

> db.x.insert({name: [null]})
> db.x.insert({name: [undefined]})
> db.x.insert({name: ['test']})
> db.x.find()
{ "_id" : ObjectId("529d5c8122de5335bffe0b79"), "name" : [  null ] }
{ "_id" : ObjectId("529d5c8422de5335bffe0b7a"), "name" : [  null ] }
{ "_id" : ObjectId("529d5c8722de5335bffe0b7b"), "name" : [  "test" ] }
> db.x.find({name: {$in: [undefined]}})
{ "_id" : ObjectId("529d5c8422de5335bffe0b7a"), "name" : [  null ] }

See how the find matches 1 document (not 2 or 0)? That's because the two nulls in the first find are different!

We should probably try to make Minimongo match Mongo better, but frankly avoiding undefined in your Mongo queries would be advisable.

datacarl

datacarl commented on Dec 3, 2013

@datacarl
ContributorAuthor

Thanks for the detailed response! I'll stay away from undefined!

dotnetwise

dotnetwise commented on Oct 28, 2015

@dotnetwise

undefined properties should be ignored at the time of serialization - otherwise you need to delete a property by using the very slow operator delete. Please reopen this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @glasser@dotnetwise@datacarl

        Issue actions

          minimongo use of `undefined` doesn't match mongo shell · Issue #1646 · meteor/meteor