$exists

语法:{ field: { $exists: <boolean> } }

如果<boolean>为true,则$exists匹配包含该字段的文档,包括字段值为的文档 null。如果<boolean>为false,则查询仅返回不包含该字段的文档。

MongoDB的$exists并没有对应的SQL操作 exists。

例子

存在且不等于

考虑以下示例:

1
db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )

该查询将选择inventory集合中该qty字段存在且其值不等于5或15的所有文档。

空值

以下示例使用以records以下文档命名的集合:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{ a: 5, b: 5, c: null }
{ a: 3, b: null, c: 8 }
{ a: null, b: 3, c: 9 }
{ a: 1, b: 2, c: 3 }
{ a: 2, c: 5 }
{ a: 3, b: 2 }
{ a: 4 }
{ b: 2, c: 4 }
{ b: 2 }
{ c: 6 }

$exists: true

以下查询指定查询:a: { $exists: true }

1
db.records.find( { a: { $exists: true } } )

结果由包含字段a的文档组成,包括其字段a包含空值的文档:

1
2
3
4
5
6
7
{ a: 5, b: 5, c: null }
{ a: 3, b: null, c: 8 }
{ a: null, b: 3, c: 9 }
{ a: 1, b: 2, c: 3 }
{ a: 2, c: 5 }
{ a: 3, b: 2 }
{ a: 4 }

$exists: false

以下查询指定查询:b: { $exists: false }

1
db.records.find( { b: { $exists: false } } )

结果由不包含该字段的那些文档组成 b:

1
2
3
{ a: 2, c: 5 }
{ a: 4 }
{ c: 6 }

$type

$type选择文档,其中字段的值是指定BSON类型的实例。在处理数据类型不可预测的高度非结构化数据时,按数据类型查询很有用。

$type单个表达BSON类型的语法如下:

在版本3.2中更改。

1
{ field: { $type: <BSON type> } }

您可以为BSON类型指定数字或别名

该$type表达式还可以接受BSON类型的数组,并具有以下语法:

1
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }

上面的查询将匹配field值是任何列出的类型的文档。数组中指定的类型可以是数字或字符串别名。

有关示例,请参见按多种数据类型查询。

可用类型描述BSON类型及其对应的数字和字符串别名。

特性

$type返回字段的BSON类型与传递给$type的BSON类型匹配的文档。

数组

对于其中field是数组的文档,$ type返回的文档中至少有一个array元素与传递给$ type的类型匹配。

查询数组BSON类型

在MongoDB 3.6和更高版本中,查询$type:“array”会返回文档,其中字段本身是数组。在MongoDB 3.6之前,$type:“array”返回文档,其中该字段是一个包含至少一个type类型元素的数组。

1
2
{ "data" : [ "values", [ "values" ] ] }
{ "data" : [ "values" ] }

在MongoDB 3.6和更高版本中,find( {"data" : { $type : "array" } } )查询将返回两个文档。在MongoDB 3.6之前,查询仅返回第一个文档。

可用类型

从MongoDB 3.2开始,$type除了接受与BSON类型相对应的数字外,还接受BSON类型的字符串别名。以前的版本仅接受与BSON类型相对应的数字。

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支持number别名,它将与以下BSON类型匹配:

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

MinKey和MaxKey

MinKey和 MaxKey 用于比较操作,主要用于内部使用。对于所有可能的BSON元素值,MinKey将始终为最小值,而MaxKey始终为最大值。

使用$type查询minKey或maxKey 只会返回与特殊MinKey或MaxKey值匹配的字段。

假设该data集合有两个文档,MinKey并且具有和MaxKey:

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

以下查询将返回带有以下内容的文档:_id: 1

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

以下查询将返回带有以下内容的文档:_id: 2

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

例子

按数据类型查询

在addressBook包含地址和邮编,在那里 zipCode有string,int,double,和long 值:

1
2
3
4
5
6
7
8
9
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) },
      { "_id" : 5, address : "104 Venus Drive", zipCode : ["834847278", "1893289032"]}
   ]
)

以下查询返回的所有文件,其中zipCode是 BSON类型string 或为含有指定的类型的元素的数组:

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

这些查询返回:

1
2
{ "_id" : 1, "address" : "2030 Martian Way", "zipCode" : "90698345" }
{ "_id" : 5, address : "104 Venus Drive", zipCOde : ["834847278", "1893289032"]}

以下查询返回的所有文件,其中zipCode是 BSON类型double 或为含有指定的类型的元素的数组:

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

这些查询返回:

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

以下查询使用的number别名返回文档,其中 zipCode是BSON类型double,int或long 或者是包含指定类型的元素的数组:

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

这些查询返回:

1
2
3
{ "_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 }

通过多数据类型查询

该grades集合包含名称和平均数,其中 classAverage有string,int和double值:

1
2
3
4
5
6
7
8
db.grades.insertMany(
   [
      { "_id" : 1, name : "Alice King" , classAverage : 87.333333333333333 },
      { "_id" : 2, name : "Bob Jenkins", classAverage : "83.52" },
      { "_id" : 3, name : "Cathy Hart", classAverage: "94.06" },
      { "_id" : 4, name : "Drew Williams" , classAverage : 93 }
   ]
)

以下查询返回的所有文件,其中classAverage是 BSON类型string或double 或为含有指定类型的元素的数组。第一个查询使用数字别名,而第二个查询使用字符串别名。

1
2
db.grades.find( { "classAverage" : { $type : [ 2 , 1 ] } } );
db.grades.find( { "classAverage" : { $type : [ "string" , "double" ] } } );

这些查询返回以下文档:

1
2
3
{ "_id" : 1, name : "Alice King" , classAverage : 87.333333333333333 }
{ "_id" : 2, name : "Bob Jenkins", classAverage : "83.52" }
{ "_id" : 3, name : "Cathy Hart", classAverage: "94.06" }

通过MinKey和MaxKey进行查询

该restaurants集合使用minKey代表不及格:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
   "_id": 1,
   "address": {
      "building": "230",
      "coord": [ -73.996089, 40.675018 ],
      "street": "Huntington St",
      "zipcode": "11231"
   },
   "borough": "Brooklyn",
   "cuisine": "Bakery",
   "grades": [
      { "date": new Date(1393804800000), "grade": "C", "score": 15 },
      { "date": new Date(1378857600000), "grade": "C", "score": 16 },
      { "date": new Date(1358985600000), "grade": MinKey(), "score": 30 },
      { "date": new Date(1322006400000), "grade": "C", "score": 15 }
   ],
   "name": "Dirty Dan's Donuts",
   "restaurant_id": "30075445"
}

而maxKey对于任何级别是最高的及格分数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
   "_id": 2,
   "address": {
      "building": "1166",
      "coord": [ -73.955184, 40.738589 ],
      "street": "Manhattan Ave",
      "zipcode": "11222"
   },
   "borough": "Brooklyn",
   "cuisine": "Bakery",
   "grades": [
      { "date": new Date(1393804800000), "grade": MaxKey(), "score": 2 },
      { "date": new Date(1378857600000), "grade": "B", "score": 6 },
      { "date": new Date(1358985600000), "grade": MaxKey(), "score": 3 },
      { "date": new Date(1322006400000), "grade": "B", "score": 5 }
   ],
   "name": "Dainty Daisey's Donuts",
   "restaurant_id": "30075449"
}

以下查询返回其grades.grade字段包含minKey 或为包含指定类型的元素的数组的任何restaurant:

1
2
3
db.restaurants.find(
   { "grades.grade" : { $type : "minKey" } }
)

这返回

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
   "_id" : 1,
   "address" : {
      "building" : "230",
      "coord" : [ -73.996089, 40.675018 ],
      "street" : "Huntington St",
      "zipcode" : "11231"
   },
   "borough" : "Brooklyn",
   "cuisine" : "Bakery",
   "grades" : [
      { "date" : ISODate("2014-03-03T00:00:00Z"), "grade" : "C", "score" : 15 },
      { "date" : ISODate("2013-09-11T00:00:00Z"), "grade" : "C", "score" : 16 },
      { "date" : ISODate("2013-01-24T00:00:00Z"), "grade" : { "$minKey" : 1 }, "score" : 30 },
      { "date" : ISODate("2011-11-23T00:00:00Z"), "grade" : "C", "score" : 15 }
   ],
   "name" : "Dirty Dan's Donuts",
   "restaurant_id" : "30075445"
}

以下查询返回其grades.grade字段包含maxKey 或为包含指定类型的元素的数组的任何餐厅:

1
2
3
db.restaurants.find(
   { "grades.grade" : { $type : "maxKey" } }
)

这返回

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
   "_id" : 2,
   "address" : {
      "building" : "1166",
      "coord" : [ -73.955184, 40.738589 ],
      "street" : "Manhattan Ave",
      "zipcode" : "11222"
   },
   "borough" : "Brooklyn",
   "cuisine" : "Bakery",
   "grades" : [
      { "date" : ISODate("2014-03-03T00:00:00Z"), "grade" : { "$maxKey" : 1 }, "score" : 2 },
      { "date" : ISODate("2013-09-11T00:00:00Z"), "grade" : "B", "score" : 6 },
      { "date" : ISODate("2013-01-24T00:00:00Z"), "grade" : { "$maxKey" : 1 }, "score" : 3 },
      { "date" : ISODate("2011-11-23T00:00:00Z"), "grade" : "B", "score" : 5 }
   ],
   "name" : "Dainty Daisey's Donuts",
   "restaurant_id" : "30075449"
}

由数组类型查询

集合SensorReading包含以下文档:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
   "_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
}

以下查询返回readings字段为空或非空数组的任何文档。

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

上面的查询返回以下文档:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
   "_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:1,_id:2,_id:3和_id:4的文档中,readings字段是一个数组。