《MongoDB入门教程》第10篇 元素运算符

Posted 不剪发的Tony老师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《MongoDB入门教程》第10篇 元素运算符相关的知识,希望对你有一定的参考价值。

本文将会介绍 MongoDB 中的两个元素查询运算符:$exists 以及 $type。

$exists 运算符

$exists 是一个元素查询运算符,语法如下:

 field:  $exists: <boolean_value>  

如果 <boolean_value> 设置为 true,$exists 运算符将会匹配指定字段存在数值的文档,数值可以是 null。

如果 <boolean_value> 设置为 false,$exists 运算符将会匹配不包含指定字段的文档。

MongoDB 中的 $exists 运算符并不等价于 SQL 中的 EXISTS 运算符。

从 MongoDB 4.2 开始,$type: 0 不等价于 $exists:false。

接下来的示例将会使用以下 products 集合:

db.products.insertMany([
	 "_id" : 1, "name" : "xPhone", "price" : 799, "releaseDate" : ISODate("2011-05-14T00:00:00Z"), "spec" :  "ram" : 4, "screen" : 6.5, "cpu" : 2.66 , "color" : [ "white", "black" ], "storage" : [ 64, 128, 256 ] ,
	 "_id" : 2, "name" : "xTablet", "price" : 899, "releaseDate" : ISODate("2011-09-01T00:00:00Z"), "spec" :  "ram" : 16, "screen" : 9.5, "cpu" : 3.66 , "color" : [ "white", "black", "purple" ], "storage" : [ 128, 256, 512 ] ,
	 "_id" : 3, "name" : "SmartTablet", "price" : 899, "releaseDate" : ISODate("2015-01-14T00:00:00Z"), "spec" :  "ram" : 12, "screen" : 9.7, "cpu" : 3.66 , "color" : [ "blue" ], "storage" : [ 16, 64, 128 ] ,
	 "_id" : 4, "name" : "SmartPad", "price" : 699, "releaseDate" : ISODate("2020-05-14T00:00:00Z"), "spec" :  "ram" : 8, "screen" : 9.7, "cpu" : 1.66 , "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256, 1024 ] ,
	 "_id" : 5, "name" : "SmartPhone", "price" : 599, "releaseDate" : ISODate("2022-09-14T00:00:00Z"), "spec" :  "ram" : 4, "screen" : 9.7, "cpu" : 1.66 , "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256 ] ,
	 "_id" : 6, "name" : "xWidget", "spec" :  "ram" : 64, "screen" : 9.7, "cpu" : 3.66 , "color" : [ "black" ], "storage" : [ 1024 ] ,
	 "_id" : 7, "name" : "xReader","price": null, "spec" :  "ram" : 64, "screen" : 6.7, "cpu" : 3.66 , "color" : [ "black", "white" ], "storage" : [ 128 ] 
])

以下示例使用 $exists 运算符查找包含 price 字段的文档:

db.products.find(
   
 price: 
 $exists: true
  
, 
   
 name: 1,
 price: 1
 
)

查询返回的文档如下:

 "_id" : 1, "name" : "xPhone", "price" : 799 
 "_id" : 2, "name" : "xTablet", "price" : 899 
 "_id" : 3, "name" : "SmartTablet", "price" : 899 
 "_id" : 4, "name" : "SmartPad", "price" : 699 
 "_id" : 5, "name" : "SmartPhone", "price" : 599 
 "_id" : 7, "name" : "xReader", "price" : null 

以下查询使用 $exists 运算符查找包含 price 字段并且价格大于 799 的文档:

db.products.find(
    price: 
        $exists: true,
        $gt: 699
    
, 
    name: 1,
    price: 1
);

输出结果如下:

 "_id" : 1, "name" : "xPhone", "price" : 799 
 "_id" : 2, "name" : "xTablet", "price" : 899 
 "_id" : 3, "name" : "SmartTablet", "price" : 899 

下面的示例使用 $exists 运算符查找不包含 price 字段的文档:

db.products.find(
    price: 
        $exists: false
    
, 
    name: 1,
    price: 1
);

查询返回了没有价格的产品:

 "_id" : 6, "name" : "xWidget" 

$type 运算符

有时候我们需要处理非结构化的数据,而它们没有明确的数据类型。此时,我们就需要使用 $type 运算符。

$type 是一个元素查询运算符,可以查找字段为指定 BSON 类型的文档。

$type 运算符的语法如下:

 field:  $type: <BSON type>  

$type 运算符也支持 BSON 类型组成的列表参数:

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

以上语法中,$type 运算符可以查找字段属于参数列表中任一 BSON 类型的文档。

MongoDB 提供了三种指定 BSON 类型的方法:类型名称、数字编号以及别名。下表列出了这三种方法对应的 BSON 类型:

类型编号别名
Double1“double”
String2“string”
Object3“object”
Array4“array”
Binary data5“binData”
ObjectId7“objectId”
Boolean8“bool”
Date9“date”
Null10“null”
Regular Expression11“regex”
javascript13“javascript”
32-bit integer16“int”
Timestamp17“timestamp”
64-bit integer18“long”
Decimal12819“decimal”
Min key-1“minKey”
Max key127“maxKey”

另外,别名“number”可以匹配以下 BSON 类型:

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

下面的示例我们需要使用新的 products 集合:

db.products.insertMany([
	 "_id" : 1, "name" : "xPhone", "price" : "799", "releaseDate" : ISODate("2011-05-14T00:00:00Z"), "spec" :  "ram" : 4, "screen" : 6.5, "cpu" : 2.66 , "color" : [ "white", "black" ], "storage" : [ 64, 128, 256 ] ,
	 "_id" : 2, "name" : "xTablet", "price" : NumberInt(899), "releaseDate" : ISODate("2011-09-01T00:00:00Z"), "spec" :  "ram" : 16, "screen" : 9.5, "cpu" : 3.66 , "color" : [ "white", "black", "purple" ], "storage" : [ 128, 256, 512 ] ,
	 "_id" : 3, "name" : "SmartTablet", "price" : NumberLong(899), "releaseDate" : ISODate("2015-01-14T00:00:00Z"), "spec" :  "ram" : 12, "screen" : 9.7, "cpu" : 3.66 , "color" : [ "blue" ], "storage" : [ 16, 64, 128 ] ,
	 "_id" : 4, "name" : "SmartPad", "price" : [599, 699, 799], "releaseDate" : ISODate("2020-05-14T00:00:00Z"), "spec" :  "ram" : 8, "screen" : 9.7, "cpu" : 1.66 , "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256, 1024 ] ,
	 "_id" : 5, "name" : "SmartPhone", "price" : ["599",699], "releaseDate" : ISODate("2022-09-14T00:00:00Z"), "spec" :  "ram" : 4, "screen" : 9.7, "cpu" : 1.66 , "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256 ] ,
	 "_id" : 6, "name" : "xWidget", "spec" :  "ram" : 64, "screen" : 9.7, "cpu" : 3.66 , "color" : [ "black" ], "storage" : [ 1024 ] 
])

products 集合中的 price 字段可能是 int、double 或者 long 类型。

以下示例使用 $type 运算符查找 price 字段属于字符串类型,或者 price 字段是包含字符串元素的数组的文档:

db.products.find(
    price: 
        $type: "string"
    
, 
    name: 1,
    price: 1
)

查询返回的结果如下:

 "_id" : 1, "name" : "xPhone", "price" : "799" 
 "_id" : 5, "name" : "SmartPhone", "price" : [ "599", 699 ] 

字符串类型对应编号为 2,我们也可以在查询中使用数字编号 2 实现相同的结果:

db.products.find(
    price: 
        $type: 2
    
, 
    name: 1,
    price: 1
)

以下示例使用 $type 运算符和别名“number”查找 price 字段属于 int、long 或者 double 类型,或者 price 字段是包含数字的数组的文档:

db.products.find(
    price: 
        $type: "number"
    
, 
    name: 1,
    price: 1
)

查询返回的文档如下:

 "_id" : 2, "name" : "xTablet", "price" : 899 
 "_id" : 3, "name" : "SmartTablet", "price" : NumberLong(899) 
 "_id" : 4, "name" : "SmartPad", "price" : [ 599, 699, 799 ] 
 "_id" : 5, "name" : "SmartPhone", "price" : [ "599", 699 ] 

以下示例使用 $type 运算符查找 price 字段属于数字或者字符串类型,或者 price 字段是包含数字或者字符串元素的数组的文档:

db.products.find(
    price: 
        $type: ["number", "string"]
    
, 
    name: 1,
    price: 1
)

查询返回的结果如下:

 "_id" : 1, "name" : "xPhone", "price" : "799" 
 "_id" : 2, "name" : "xTablet", "price" : 899 
 "_id" : 3, "name" : "SmartTablet", "price" : NumberLong(899) 
 "_id" : 4, "name" : "SmartPad", "price" : [ 599, 699, 799 ] 
 "_id" : 5, "name" : "SmartPhone", "price" : [ "599", 699 ] 

查询结果中没有包含 _id 等于 6 的文档,因为该文档中没有 price 字段。

以上是关于《MongoDB入门教程》第10篇 元素运算符的主要内容,如果未能解决你的问题,请参考以下文章

《MongoDB入门教程》第10篇 元素运算符

《MongoDB入门教程》第11篇 数组运算符

《MongoDB入门教程》第11篇 数组运算符

《MongoDB入门教程》第11篇 数组运算符

《MongoDB入门教程》第09篇 逻辑运算符

《MongoDB入门教程》第09篇 逻辑运算符