Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find by $type number in mongodb

Tags:

mongodb

I've got following documents

> db.people.insert({name: "Bob"})
> db.people.insert({name: 42})

If I need find by type String I can use:

> db.people.find({name: { $type: 2 })

Where 2 is Type Number of String

But how could I find by type Number?

> typeof db.people.findOne({name: 42}).name
number

There is no type number in possible types.

upd: I've tried to find by 16 and 18 types. It's not works.

> db.people.find({ name: 42 })
{ "_id" : ObjectId("509645ae5013826ee61d96ac"), "name" : 42 }
> db.people.find({name: { $type: 16 }})
> db.people.find({name: { $type: 18 }})
like image 981
ck3g Avatar asked Nov 04 '12 10:11

ck3g


1 Answers

There is only one numeric type in JavaScript (Number), which is represented in binary as an IEEE 754 floating point number (double).

In the BSON spec this will be represented as a double (type 1), so you should be able to find with:

db.people.find({name: { $type: 1 }})

There are some mongo shell helpers if you want to insert different BSON data types:

42              // Type 1:  double (64-bit IEEE 754 floating point, 8 bytes)
NumberInt(42)   // Type 16: int32  (32-bit signed integer, 4 bytes)
NumberLong(42)  // Type 18: int64  (64-bit signed integer, 8 bytes)

So for example:

db.people.insert({ name: 'default', num: 42 })
db.people.insert({ name: 'NumberLong', num: NumberLong(42) })
db.people.insert({ name: 'NumberInt', num: NumberInt(42) })

The different numeric representations will still match if you do a find() on a number that can be represented in multiple formats (i.e. a 32-bit integer can also be represented as a double or int64).

For example:

db.people.find({num:42})
{
    "_id" : ObjectId("50965aa3038d8c8e85fd3f45"),
    "name" : "default",
    "num" : 42
}
{
    "_id" : ObjectId("50965aa3038d8c8e85fd3f46"),
    "name" : "NumberLong",
    "num" : NumberLong(42)
}
{
    "_id" : ObjectId("50965aa3038d8c8e85fd3f47"),
    "name" : "NumberInt",
    "num" : 42
}

However if you find by $type, the BSON representation is different:

> db.people.find({num: { $type: 1 }})
{
    "_id" : ObjectId("50965aa3038d8c8e85fd3f45"),
    "name" : "default",
    "num" : 42
}

> db.people.find({num: { $type: 16 }})
{
    "_id" : ObjectId("50965aa3038d8c8e85fd3f47"),
    "name" : "NumberInt",
    "num" : 42
}

> db.people.find({num: { $type: 18 }})
{
    "_id" : ObjectId("50965aa3038d8c8e85fd3f46"),
    "name" : "NumberLong",
    "num" : NumberLong(42)
}
like image 69
Stennie Avatar answered Sep 22 '22 11:09

Stennie