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


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

    $exists 运算符

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

    { field: { $exists: <boolean_value> } }
    
    • 1

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

    如果 设置为 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 ] }
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    db.products.find(
       {
     price: {
     $exists: true
     } 
    }, 
       {
     name: 1,
     price: 1
     }
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    查询返回的文档如下:

    { "_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 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    db.products.find({
        price: {
            $exists: true,
            $gt: 699
        }
    }, {
        name: 1,
        price: 1
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输出结果如下:

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

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

    db.products.find({
        price: {
            $exists: false
        }
    }, {
        name: 1,
        price: 1
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    { "_id" : 6, "name" : "xWidget" }
    
    • 1

    $type 运算符

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

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

    $type 运算符的语法如下:

    { field: { $type: <BSON type> } }
    
    • 1

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

    { field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
    
    • 1

    以上语法中,$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 ] }
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

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

    db.products.find({
        price: {
            $type: "string"
        }
    }, {
        name: 1,
        price: 1
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查询返回的结果如下:

    { "_id" : 1, "name" : "xPhone", "price" : "799" }
    { "_id" : 5, "name" : "SmartPhone", "price" : [ "599", 699 ] }
    
    • 1
    • 2

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

    db.products.find({
        price: {
            $type: 2
        }
    }, {
        name: 1,
        price: 1
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    db.products.find({
        price: {
            $type: "number"
        }
    }, {
        name: 1,
        price: 1
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查询返回的文档如下:

    { "_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 ] }
    
    • 1
    • 2
    • 3
    • 4

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

    db.products.find({
        price: {
            $type: ["number", "string"]
        }
    }, {
        name: 1,
        price: 1
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查询返回的结果如下:

    { "_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 ] }
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

  • 相关阅读:
    【MM小贴士】副产品 工单核算
    C++_第八周做题总结
    FreqBlender: Enhancing DeepFake Detection by Blending Frequency Knowledge
    找免费商用字体,就上这5个网站,再也不怕侵权了。
    KubeCube 新增版本转换:K8s 尝鲜再也不用担心影响老版本了
    Spring的Factories机制介绍
    C++代码示例:组合数简单生成工具
    Hive sql 行列转换(行转列,列转行)
    Java转义工具类StringEscapeUtils的学习笔记
    【Spring源码解析】一文读懂Spring注入模型:开发者必备知识
  • 原文地址:https://blog.csdn.net/horses/article/details/126267674