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" : [ ]
}
相关推荐
小诗懂技术4 小时前
【sqlite3数据库】一站式学会 增删改查 以及数据库c接口编程
数据库·sqlite
风123456789~4 小时前
【架构专栏】第6章 数据库设计基础知识 4/4
数据库·架构
IvorySQL4 小时前
代价比较的变革——PostgreSQL执行计划干预增强深度解析
数据库·postgresql·ffmpeg
SL-staff4 小时前
离散制造企业如何应对频繁插单?智能排产系统带来新思路
大数据·数据库·人工智能·技术教程·智能排产·jvs-aps·排产系统
码云数智-园园4 小时前
Oracle 锁等待、会话阻塞故障复盘:生产事故排查步骤
数据库·oracle
哈__5 小时前
从 MySQL 到在线表格:NocoDB 自托管部署、数据导入与远程访问
数据库·mysql
倔强的石头1066 小时前
高可用与无感扩容——分布式时序数据库选型指南
数据库·分布式·时序数据库
袋鼠云数栈15 小时前
实时湖仓如何真正做到“数据够新”?
大数据·数据库·人工智能·数据治理
ACP广源盛1392462567315 小时前
M6/M5 Pro Mac mini 端侧 AI 落地@ACP#YLB3116 中端多盘存储扩展在 AI 服务中的机会与应用场景
大数据·网络·数据库·人工智能·嵌入式硬件·macos
ACP广源盛1392462567315 小时前
M6/M5 Pro Mac mini 端侧 AI 新形态@ACP#GSV5800 Serdes 长距离视频传输在 AI 服务中的机会与落地场景
大数据·网络·数据库·人工智能·嵌入式硬件·macos·音视频