MongoDB使用$type查询指定字段类型的文档

目录

语法

行为

应用

按照数据类型查询文档

查询符合多个类型的文档

使用minKey和maxKey查询文档

查询数组类型的字段


Mongodb集合中的文档结构灵活,不要求具有同一的格式。因此不同的字段可能带有不同类型的值。灵活的结构,为数据的写入带来了方便, 但后面的查询操作,可能会造成一定的麻烦。用户或应用程序需要考虑当前字段值的类型是什么。如果进行数值运算,则要将字符类型和其他类型的字段转化为数字类型。 mongodb提供了$type来按照指定的类型来查询文档。

语法

复制代码
{"<field_name>": {$type: <BSON_type>}}

其中, BSON_type可以是BSON类型的数字代码或字符别名

复制代码
{"<field_name>": {$type: [<BSON_type_1>,<BSON_type_2>]}}

其中,BSON_type1, BSON_type_2是BSON类型的数字代码或字符别名。

这里不允许使用in操作符,而是直接在type中指定类型数组。

行为

  • 利用$type操作符,查询出字段类型符合指定类型的数据
  • 当字段是数组时,若数组中的任何一个值符合$type操作符中指定的类型,该字段所在的文档也会被查出来
  • 当$type指定查询类型是数组时, 返回该字段是数组类型的文档,无论该数组是否为空
  • 指定$type类型为number类型是, double, 32位整型,64位整型和小数类型decimal都会被查出来。
  • 使用minKey和maxKey类型查询时, 数据库会返回字段值是Minkey()或MaxKey()的文档。MinKey和MaxKey用在比较运算当中,而且基本上保留内部使用。在所有BSON元素值中, Minkey是最小的, 而MaxKey是最大的。

有下面包含最小值和最大值的两个文档

复制代码
db.minMax.insertMany([{
    _id: 1, x: MinKey()
},{
    _id: 2, y: MaxKey()
}])

//查询x字段是minKey的文档
db.minMax.find({x: {$type: "minKey"}})
//查询Y字段是maxKey的文档
db.minMax.find({y: {$type: "maxKey"}})

应用

按照数据类型查询文档

在集合addressBook中,包含了地址address字段和邮编zipcodes文档。 其中zipCode字段包含字符,整型,长整型,数组等多种类型。

复制代码
db.addressbook.insertMany([
    {"_id": 1, address: "2030 Martain 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字段为字符类型,或者zipCode数组值中包含字符类型的文档。

复制代码
db.addressbook.find( {zipCode: {$type: 2}})
db.addressbook.find( {zipCode: {$type: "string"}})
//返回数据
/* 1 */
{
	"_id" : 1,
	"address" : "2030 Martain Way",
	"zipCode" : "90698345" //字段类型为字符
},

/* 2 */
{
	"_id" : 5,
	"address" : "104 Venus Drive",
	"zipCode" : [ "834847278", "1893289032" ] //字段类型为数组,数组中包含字符类型的元素
}

查询字段类型是整型类型的数据

复制代码
db.addressbook.find( {zipCode: {$type: 16}})
db.addressbook.find( {zipCode: {$type: 'int'}})

/* 1 */
{
	"_id" : 2,
	"address" : "156 Lunar Place",
	"zipCode" : 43339374 //整型类型
},

/* 2 */
{
	"_id" : 4,
	"address" : "55 Saturn Ring",
	"zipCode" : 88602117    //整型类型
}

查询字段类型为数值类型的文档。 该查询返回字段类型为double, int, long, decimal和数组中包含数值类型的文档

复制代码
db.addressbook.find( {zipCode: {$type: 'number'}})

/* 1 */
{
	"_id" : 2,
	"address" : "156 Lunar Place",
	"zipCode" : 43339374 //整型
},

/* 2 */
{
	"_id" : 3,
	"address" : "2324 Pluto Place",
	"zipCode" : Long("3921412") //长整型
},

/* 3 */
{
	"_id" : 4,
	"address" : "55 Saturn Ring",
	"zipCode" : 88602117 //整型
}

查询符合多个类型的文档

在集合grades中包含字段name和classAverage, 其中classAverage字段具有字符串类型,整型和浮点型的数据。

复制代码
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: NumberInt("93")}
])

查询出字段classAverage是字符串类型和浮点类型的文档

复制代码
db.grades.find( {classAverage: {$type: [2,1]}})
db.grades.find( {classAverage: {$type: ["string", "double"]}})
/* 1 */
{
	"_id" : 1,
	"name" : "Alice King",
	"classAverage" : 87.33333333333333 //浮点类型
},

/* 2 */
{
	"_id" : 2,
	"name" : "Bob Jenkins",
	"classAverage" : "83.52" //字符串
},

/* 3 */
{
	"_id" : 3,
	"name" : "Cathy hart",
	"classAverage" : "94.06" //字符串
}

type中使用in操作符会报错。

复制代码
db.grades.find( {classAverage: {$type: {$in: ["string", "double"]}}}) //错误用法
{
	"message" : "type must be represented as a number or a string",
	"ok" : 0,
	"code" : 14,
	"codeName" : "TypeMismatch"
}

使用minKey和maxKey查询文档

在一个酒店的每日管理过程中, 将用户评分为不及格的评价,记录为最小值minKey, 用户评分的最高分记录为最大值maxKey.

复制代码
db.restaurants.insertMany([{
    "_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"
},{
    "_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"
}])

使用最小值或最大值查询用户评价

复制代码
db.restaurants.find({"grades.grade": { $type: "minKey"}})
db.restaurants.find({"grades.grade": { $type: "maxKey"}})

查询数组类型的字段

在集合sensorReading中, 包含了数组类型的传感器读取数据

复制代码
db.sensorReading.insertMany([{
    "_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是数组类型的文档。 无论数组是否为空,都会被查询出来。

复制代码
db.sensorReading.find( {readings: {$type: "array"}})

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

/* 2 */
{
	"_id" : 2,
	"readings" : [ 25, 25, 24, 23 ]
},

/* 3 */
{
	"_id" : 3,
	"readings" : [
		22,
		24,
		[ ]
	]
},

/* 4 */
{
	"_id" : 4,
	"readings" : [ ]
}
相关推荐
2301_8025023337 分钟前
哈工大计算机系统2025大作业——Hello的程序人生
数据库·程序人生·课程设计
Alan3164 小时前
Qt 中,设置事件过滤器(Event Filter)的方式
java·开发语言·数据库
TDengine (老段)5 小时前
TDengine 集群容错与灾备
大数据·运维·数据库·oracle·时序数据库·tdengine·涛思数据
Lao A(zhou liang)的菜园6 小时前
高效DBA的日常运维主题沙龙
运维·数据库·dba
迪迦不喝可乐6 小时前
mysql知识点
数据库·mysql
不太可爱的大白7 小时前
MySQL 事务的 ACID 四大特性及其实现原理
数据库·mysql
观测云8 小时前
HikariCP 可观测性最佳实践
数据库
文牧之8 小时前
PostgreSQL的扩展 dblink
运维·数据库·postgresql
趁你还年轻_9 小时前
Redis-旁路缓存策略详解
数据库·redis·缓存
在云上(oncloudai)9 小时前
AWS DocumentDB vs MongoDB:数据库的技术抉择
数据库·mongodb·aws