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" : [ ]
}
相关推荐
sun0077003 小时前
mysql索引底层原理
数据库·mysql
workflower6 小时前
MDSE和敏捷开发相互矛盾之处:方法论本质的冲突
数据库·软件工程·敏捷流程·极限编程
Tony小周6 小时前
实现一个点击输入框可以弹出的数字软键盘控件 qt 5.12
开发语言·数据库·qt
lifallen6 小时前
Paimon 原子提交实现
java·大数据·数据结构·数据库·后端·算法
TDengine (老段)7 小时前
TDengine 数据库建模最佳实践
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
Elastic 中国社区官方博客7 小时前
Elasticsearch 字符串包含子字符串:高级查询技巧
大数据·数据库·elasticsearch·搜索引擎·全文检索·lucene
Gauss松鼠会7 小时前
GaussDB应用场景全景解析:从金融核心到物联网的分布式数据库实践
数据库·分布式·物联网·金融·database·gaussdb
守城小轩8 小时前
Chromium 136 编译指南 - Android 篇:开发工具安装(三)
android·数据库·redis
尽兴-8 小时前
如何将多个.sql文件合并成一个:Windows和Linux/Mac详细指南
linux·数据库·windows·sql·macos
小小不董8 小时前
深入理解oracle ADG和RAC
linux·服务器·数据库·oracle·dba