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

发布于:2023-01-12 ⋅ 阅读:(565) ⋅ 点赞:(0)

本文将会介绍 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 类型:

类型 编号 别名
Double 1 “double”
String 2 “string”
Object 3 “object”
Array 4 “array”
Binary data 5 “binData”
ObjectId 7 “objectId”
Boolean 8 “bool”
Date 9 “date”
Null 10 “null”
Regular Expression 11 “regex”
JavaScript 13 “javascript”
32-bit integer 16 “int”
Timestamp 17 “timestamp”
64-bit integer 18 “long”
Decimal128 19 “decimal”
Min key -1 “minKey”
Max key 127 “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 字段。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到