Navigation

$type

Definition

$type

$type selects the documents where the value of the field is an instance of the specified BSON type. Querying by data type is useful when dealing with highly unstructured data where data types are not predictable.

A $type expression has the following syntax:

Changed in version 3.2.

{ field: { $type: <BSON type number> | <String alias> } }

Available Types describes the BSON types and their corresponding numeric and string aliases.

Behavior

$type returns documents where the BSON type of the field matches the BSON type passed to $type.

Available Types

Changed in version 3.2: $type operator accepts string aliases for the BSON types in addition to the numbers corresponding to the BSON types. Previous versions only accepted the numbers corresponding to the BSON type.

Type Number Alias Notes
Double 1 “double”  
String 2 “string”  
Object 3 “object”  
Array 4 “array”  
Binary data 5 “binData”  
Undefined 6 “undefined” Deprecated.
ObjectId 7 “objectId”  
Boolean 8 “bool”  
Date 9 “date”  
Null 10 “null”  
Regular Expression 11 “regex”  
DBPointer 12 “dbPointer” Deprecated.
JavaScript 13 “javascript”  
Symbol 14 “symbol” Deprecated.
JavaScript (with scope) 15 “javascriptWithScope”  
32-bit integer 16 “int”  
Timestamp 17 “timestamp”  
64-bit integer 18 “long”  
Decimal128 19 “decimal” New in version 3.4.
Min key -1 “minKey”  
Max key 127 “maxKey”  

$type supports the number alias, which will match against the following BSON types:

  • double
  • 32-bit integer
  • 64-bit integer
  • decimal

See Querying by Data Type

Arrays

When applied to arrays, $type matches any inner element that is of the specified BSON type. For example, when matching for $type : 'array', the document will match if the field has a nested array. It will not return results where the field itself is an array.

See Querying by Array Type for an example.

MinKey and MaxKey

MinKey and MaxKey are used in comparison operations and exist primarily for internal use. For all possible BSON element values, MinKey will always be the smallest value while MaxKey will always be the greatest value.

Querying for minKey or maxKey with $type will only return fields that match the special MinKey or MaxKey values.

Suppose that the data collection has two documents with MinKey and MaxKey:

{ "_id" : 1, x : { "$minKey" : 1 } }
{ "_id" : 2, y : { "$maxKey" : 1 } }

The following query will return the document with _id: 1:

db.data.find( { x: { $type: "minKey" } } )

The following query will return the document with _id: 2:

db.data.find( { y: { $type: "maxKey" } } )

Examples

Querying by Data Type

The addressBook contains addresses and zipcodes, where zipCode has string, int, double, and long values:

db.addressBook.insertMany(
   [
      { "_id" : 1, address : "2030 Martian Way", zipCode : "90698345" },
      { "_id" : 2, address: "156 Lunar Place", zipCode : 43339374 },
      { "_id" : 3, address : "2324 Pluto Place", zipCode: NumberLong(3921412) },
      { "_id" : 4, address : "55 Saturn Ring" , zipCode : NumberInt(88602117) }
   ]
)

The following queries return all documents where zipCode is the BSON type string:

db.addressBook.find( { "zipCode" : { $type : 2 } } );
db.addressBook.find( { "zipCode" : { $type : "string" } } );

These queries return:

{ "_id" : 1, "address" : "2030 Martian Way", "zipCode" : "90698345" }

The following queries return all documents where zipCode is the BSON type double:

db.addressBook.find( { "zipCode" : { $type : 1 } } )
db.addressBook.find( { "zipCode" : { $type : "double" } } )

These queries return:

{ "_id" : 2, "address" : "156 Lunar Place", "zip" : 43339374 }

The following query uses the number alias to return documents where zipCode is the BSON type double, int, or long:

db.addressBook.find( { "zipCode" : { $type : "number" } } )

These queries return:

{ "_id" : 2, address : "156 Lunar Place", zipCode : 43339374 }
{ "_id" : 3, address : "2324 Pluto Place", zipCode: NumberLong(3921412) }
{ "_id" : 4, address : "55 Saturn Ring" , zipCode : 88602117 }

Querying by MinKey and MaxKey

The restaurants collection uses minKey for any grade that is a failing grade:

{
   "_id": 1,
   "address": {
      "building": "230",
      "coord": [ -73.996089, 40.675018 ],
      "street": "Huntington St",
      "zipcode": "11231"
   },
   "borough": "Brooklyn",
   "cuisine": "Bakery",
   "grades": [
      { "date": { "$date": 1393804800000 }, "grade": "C", "score": 15 },
      { "date": { "$date": 1378857600000 }, "grade": "C", "score": 16 },
      { "date": { "$date": 1358985600000 }, "grade": { "$minKey" : 1 }, "score": 30 },
      { "date": { "$date": 1322006400000 }, "grade": "C", "score": 15 }
   ],
   "name": "Dirty Dan's Donuts",
   "restaurant_id": "30075445"
}

And maxKey for any grade that is the highest passing grade:

{
   "_id": 2,
   "address": {
      "building": "1166",
      "coord": [ -73.955184, 40.738589 ],
      "street": "Manhattan Ave",
      "zipcode": "11222"
   },
   "borough": "Brooklyn",
   "cuisine": "Bakery",
   "grades": [
      { "date": { "$date": 1393804800000 }, "grade": { "$maxKey" : 1 }, "score": 2 },
      { "date": { "$date": 1378857600000 }, "grade": "B", "score": 6 },
      { "date": { "$date": 1358985600000 }, "grade": { "$maxKey" : 1 }, "score": 3 },
      { "date": { "$date": 1322006400000 }, "grade": "B", "score": 5 }
   ],
   "name": "Dainty Daisey's Donuts",
   "restaurant_id": "30075449"
}

The following query returns any restaurant whose grades.grade field contains minKey:

db.restaurant.find(
   { "grades.grade" : { $type : "minKey" } }
)

This returns

{
   "_id": 1,
   "address": {
      "building": "230",
      "coord": [ -73.996089, 40.675018 ],
      "street": "Huntington St",
      "zipcode": "11231"
   },
   "borough": "Brooklyn",
   "cuisine": "Bakery",
   "grades": [
      { "date": { "$date": 1393804800000 }, "grade": "C", "score": 15 },
      { "date": { "$date": 1378857600000 }, "grade": "C", "score": 16 },
      { "date": { "$date": 1358985600000 }, "grade": { "$minKey" : 1 }, "score": 30 },
      { "date": { "$date": 1322006400000 }, "grade": "C", "score": 15 }
   ],
   "name": "Dirty Dan's Donuts",
   "restaurant_id": "30075445"
}

The following query returns any restaurant whose grades.grade field contains maxKey:

db.restaurant.find(
   { "grades.grade" : { $type : "maxKey" } }
)

This returns

{
   "_id": 2,
   "address": {
      "building": "1166",
      "coord": [ -73.955184, 40.738589 ],
      "street": "Manhattan Ave",
      "zipcode": "11222"
   },
   "borough": "Brooklyn",
   "cuisine": "Bakery",
   "grades": [
      { "date": { "$date": 1393804800000 }, "grade": { "$maxKey" : 1 }, "score": 2 },
      { "date": { "$date": 1378857600000 }, "grade": "B", "score": 6 },
      { "date": { "$date": 1358985600000 }, "grade": { "$maxKey" : 1 }, "score": 3 },
      { "date": { "$date": 1322006400000 }, "grade": "B", "score": 5 }
   ],
   "name": "Dainty Daisey's Donuts",
   "restaurant_id": "30075449"
}

Querying by Array Type

A collection named SensorReading contains the following documents:

{
   "_id": 1,
   "readings": [
      25,
      23,
      [ "Warn: High Temp!", 55 ],
      [ "ERROR: SYSTEM SHUTDOWN!", 66 ]
   ]
},
{
   "_id": 2,
   "readings": [
      25,
      25,
      24,
      23
   ]
},
{
   "_id": 3,
   "readings": [
      22,
      24,
      []
   ]
},
{
   "_id": 4,
   "readings": []
},
{
   "_id": 5,
   "readings": 24
}

The following query returns any document in which the readings field contains an element of BSON type array. Note that the $type query filter does not detect whether the readings field itself is an array.

db.SensorReading.find( { "readings" : { $type: "array" } } )

The above query returns the following documents:

{
   "_id": 1,
   "readings": [
      25,
      23,
      [ "Warn: High Temp!", 55 ],
      [ "ERROR: SYSTEM SHUTDOWN!", 66 ]
   ]
},
{
   "_id": 3,
   "readings": [
      22,
      24,
      []
   ]
}

In the documents with _id : 1 and _id : 3, the readings field contains at least one element which is an array, while the other documents do not.

Querying for Documents Where a Given Field is an Array

Use the following query constructions to find documents in which the specified field is itself an array.

The following query uses the $elemMatch and the $exists operator to find all documents where the readings fields is a BSON array array with one or more elements.

db.SensorReading.find( { "readings" : { $elemMatch: { $exists: true } } } )

The above query returns the following documents:

{
   "_id": 1,
   "readings": [
      25,
      23,
      [ "Warn: High Temp!", 55 ],
      [ "ERROR: SYSTEM SHUTDOWN!", 66 ]
   ]
},
{
   "_id": 2,
   "readings": [
      25,
      25,
      24,
      23
   ]
},
{
   "_id": 3,
   "readings": [
      22,
      24,
      []
   ]
}

To find all documents in the collection in which the readings field is an array, either empty or non-empty, the following query uses two clauses: the first checks whether readings is a non-empty array, and the second checks whether it is an empty array.

db.SensorReading.find( {
  $or: [
    { "readings": { $elemMatch: { $exists: true } } },
    { "readings": [] }
  ]
} )

The above query returns the first four documents in the collection and excludes the one with _id : 5, in which the readings field is an integer instead of an array.

Additional Information

find(), BSON Types.