• MongoDB 聚合管道使用


    数据准备

    [
        {
            "name": {
                "first_name": "qingquan",
                "last_name": "zeng"
            },
            "balance": 100
        },
        {
            "name": {
                "first_name": "fengxia",
                "last_name": "yu"
            },
            "balance": 200
        }
    ]
    

    插入数据

    db.accounts.insert([{"name": {"first_name": "qingquan","last_name": "zeng"},"balance": 100},{"name": {"first_name": "fengxia","last_name": "yu"},"balance": 200}])
    

    数据查询

    $project

    # aggregate 中的 $project 除了可以实现投影效果,还直接使用了一个不存在的字段 client_name ,相当于 mysql 中的 as 语法
    > db.accounts.aggregate([{
    ... $project:{
    ... _id:0,
    ... balance:1,
    ... client_name:"$name.first_name"
    ... }
    ... }]);
    { "balance" : 100, "client_name" : "qingquan" }
    { "balance" : 200, "client_name" : "fengxia" }
    
    # 由于 middle_name 不存在,产生的结果就为 null 了
    > db.accounts.aggregate([{
    ... $project:{
    ... _id:0,
    ... balance:1,
    ... name_arr:["$name.first_name","$name.middle_name","$name.first_name"]
    ... }
    ... }]);
    { "balance" : 100, "name_arr" : [ "qingquan", null, "qingquan" ] }
    { "balance" : 200, "name_arr" : [ "fengxia", null, "fengxia" ] }
    

    $match 中使用的文档筛选语法,和读取文档时的筛选语法相同

    db.accounts.aggregate([
        {
            $match: {
                "name.first_name": 'fengxia'
            }
        }
    ])
    { "_id" : ObjectId("5d80fd4471c6b2236fb80de9"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200 }
    

    $project$match$skip$limit 相结合

    db.accounts.aggregate([
        {
            $match: {
                $or: [
                    {
                        "name.first_name": 'fengxia'
                    },
                    {
                        "name.first_name": 'qingquan'
                    },          
                ]
            }
        },
        {
            $project: {
                _id: 0
            }
        },
        {
            $skip: 1
        },
        {
            $limit: 1
        }
    ])
    { "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200 }
    

    $unwind
    对本节的数据进行修改

    db.accounts.update({'name.first_name':'qingquan'},{
     $set:{
      "currency":["CNY","USD"]
     }
    })
    
    db.accounts.update({'name.first_name':'fengxia'},{
     $set:{
      "currency":"GBP"
     }
    })
    

    修改后的数据如下,一个用户的currency是数组,另一个用户的currency是字符串

    > db.accounts.find()
    { "_id" : ObjectId("5d80fd4471c6b2236fb80de8"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : [ "CNY", "USD" ] }
    { "_id" : ObjectId("5d80fd4471c6b2236fb80de9"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP" }
    

    使用unwind对数组元素进行平铺,可以将currency为数组的记录,从一条记录拆分为多条记录

    db.accounts.aggregate([
        {
            $unwind: {
                path: "$currency"
            }
        }
    ])
    { "_id" : ObjectId("5d80fd4471c6b2236fb80de8"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "CNY" }
    { "_id" : ObjectId("5d80fd4471c6b2236fb80de8"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "USD" }
    { "_id" : ObjectId("5d80fd4471c6b2236fb80de9"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP" }
    

    为了方便排查,还可以在设定一个字段,用于数组展开后标记每个元素在原数组的位置

    db.accounts.aggregate([
        {
            $unwind: {
                path: "$currency",
                includeArrayIndex:"origin_index"
            }
        }
    ])
    { "_id" : ObjectId("5d80c37349f3060f1212a055"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "CNY", "origin_index" : NumberLong(0) }
    { "_id" : ObjectId("5d80c37349f3060f1212a055"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "USD", "origin_index" : NumberLong(1) }
    { "_id" : ObjectId("5d80c37349f3060f1212a056"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP", "origin_index" : null }
    

    还有一点需要注意的是,$unwind 在产生结果前,默认会直接过滤掉如下记录:

    • currency字段为空数组
    • currency字段不存在
    • currency字段为null

    如果不想过滤的话,可以设定 preserveNullAndEmptyArrays 为 true

    db.accounts.aggregate([
        {
            $unwind: {
                path: "$currency",
                includeArrayIndex: "origin_index",
                preserveNullAndEmptyArrays: true
            }
        }
    ])
    

    $sort

    • 1 从小到大
    • -1 从大到小
    db.accounts.aggregate([
        {
            $sort: {
                balance: -1
            }
        }
    ])
    { "_id" : ObjectId("5d80c37349f3060f1212a056"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP" }
    { "_id" : ObjectId("5d80c37349f3060f1212a055"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : [ "CNY", "USD" ] }
    

    MongoDB 聚合操作重复问题https://jacoobwang.github.io/2018/01/08/MongoDb%E8%81%9A%E5%90%88%E6%93%8D%E4%BD%9C%E9%87%8D%E5%A4%8D%E9%97%AE%E9%A2%98/

  • 相关阅读:
    网络编程2018-4-23
    网络编程
    异常处理
    在Asp.net core使用配置Json创建动态目录树
    Asp.net Core中文转换成拼音
    解决Asp.Net core 控制台出现乱码的情况
    解决Asp.net Core中chtml文档中文乱码的问题
    取代Ajax.BeginForm的ajax使用方法
    将数据库模型放入到.Net Core的类库中
    如何使用Resource资源文件
  • 原文地址:https://www.cnblogs.com/zy108830/p/12639658.html
Copyright © 2020-2023  润新知