mongodb中的populate方法

嵌入式C语言实现设计模式:struct与函数指针实践 设计模式是软件工程中解决常见问题的经典方案,传统上多与面向对象语言关联。在嵌入式开发领域,通过C语言的结构体(struct)与函数指针组合,可以巧妙实现策略模式、观察者模式等经典设计模式。这种技术方案既保留了C语言的高效性和低资源占用特点,又显著提升了代码的可维护性和扩展性。在嵌入式Linux驱动开发、RTOS应用等场景中,通过结构体封装数据与操作、利用函数指针实现多态,能够有效管理硬件抽象层、事件通知等复杂逻辑。实测表明,相比条件判断等传统方法,这种实现方式在STM32等MCU上可提升20%以上的执行效率 阅读详情

Mongoose 是 MongoDB 的 ODM(Object Document Mapper)

  • 什么是ODM? 其实和ORM(Object Relational Mapper)是同类型的工具。都是将数据库的数据转化为代码对象的库,使用转化后的对象可以直接对数据库的数据进行CRUD(增删改查)
  • MongoDB 是文档型数据库(Document Database),不是关系型数据库(Relational Database)。而Mongoose可以将 MongonDB 数据库存储的文档(documents)转化为 javascript 对象,然后可以直接进行数据的增删改查。

因为MongoDB是文档型数据库,所以它没有关系型数据库[joins](http://zh.wikipedia.org/wiki/%E8%BF%9E%E6%8E%A5_(SQL)(数据库的两张表通过"外键",建立连接关系。) 特性。也就是在建立数据的关联时会比较麻烦。为了解决这个问题,Mongoose封装了一个Population功能。使用Population可以实现在一个 document 中填充其他 collection(s) 的 document(s)

在定义Schema的时候,如果设置某个 field 关联另一个Schema,那么在获取 document 的时候就可以使用 Population 功能通过关联Schema的 field 找到关联的另一个 document,并且用被关联 document 的内容替换掉原来关联字段(field)的内容。

接下来分享下:Query#populate Model#populate Document#populate的用法

先建立三个SchemaModel:

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var UserSchema = new Schema({
    name  : { type: String, unique: true },
    posts : [{ type: Schema.Types.ObjectId, ref: 'Post' }]
});
var User = mongoose.model('User', UserSchema);

var PostSchema = new Schema({
    poster   : { type: Schema.Types.ObjectId, ref: 'User' },
    comments : [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
    title    : String,
    content  : String
});
var Post = mongoose.model('Post', PostSchema);

var CommentSchema = new Schema({
    post      : { type: Schema.Types.ObjectId, ref: "Post" },
    commenter : { type: Schema.Types.ObjectId, ref: 'User' },
    content   : String
});
var Comment = mongoose.model('Comment', CommentSchema);

  • 在上述的例子中,创建了三个 Models:UserPostComment
  • User 的属性 posts,对应是一个 ObjectId 的数组。ref表示关联Post(注意: 被关联的model的 type 必须是ObjectId, Number, String, 和 Buffer 才有效)。
  • Post的属性 poster 和 comments 分别关联UserComment
  • Comment的属性 post 和 commenter 分别关联PostUser
  • 三个 Models 的关系:一个 user--has many-->post。一个 post--has one-->user,has many-->comment。一个 comment--has one-->post 和 user。

创建一些数据到数据库:

// 连接数据库
mongoose.connect('mongodb://localhost/population-test', function (err){
    if (err) throw err;
    createData();
});

function createData() {

    var userIds    = [new ObjectId, new ObjectId, new ObjectId];
    var postIds    = [new ObjectId, new ObjectId, new ObjectId];
    var commentIds = [new ObjectId, new ObjectId, new ObjectId];

    var users    = [];
    var posts    = [];
    var comments = [];

    users.push({
        _id   : userIds[0],
        name  : 'aikin',
        posts : [postIds[0]]
    });
    users.push({
        _id   : userIds[1],
        name  : 'luna',
        posts : [postIds[1]]
    });
    users.push({
        _id   : userIds[2],
        name  : 'luajin',
        posts : [postIds[2]]
    });

    posts.push({
        _id      : postIds[0],
        title    : 'post-by-aikin',
        poster   : userIds[0],
        comments : [commentIds[0]]
    });
    posts.push({
        _id      : postIds[1],
        title    : 'post-by-luna',
        poster   : userIds[1],
        comments : [commentIds[1]]
    });
    posts.push({
        _id      : postIds[2],
        title    : 'post-by-luajin',
        poster   : userIds[2],
        comments : [commentIds[2]]
    });

    comments.push({
        _id       : commentIds[0],
        content   : 'comment-by-luna',
        commenter : userIds[1],
        post      : postIds[0]
    });
    comments.push({
        _id       : commentIds[1],
        content   : 'comment-by-luajin',
        commenter : userIds[2],
        post      : postIds[1]
    });
    comments.push({
        _id       : commentIds[2],
        content   : 'comment-by-aikin',
        commenter : userIds[1],
        post      : postIds[2]
    });

    User.create(users, function(err, docs) {
        Post.create(posts, function(err, docs) {
            Comment.create(comments, function(err, docs) {
            });
        });
    });
}

数据的准备就绪后,接下来就是探索populate方法:

1. Query#populate

什么Query? Query(查询),可以快速和简单的从MongooDB查找出相应的 document(s)。 Mongoose 封装了很多查询的方法,使得对数据库的操作变得简单啦。这里分享一下populate方法用法。

语法:
Query.populate(path, [select], [model], [match], [options])

参数:

path
  类型:StringObject
  String类型的时, 指定要填充的关联字段,要填充多个关联字段可以以空格分隔。
  Object类型的时,就是把 populate 的参数封装到一个对象里。当然也可以是个数组。下面的例子中将会实现。

select
  类型:ObjectString,可选,指定填充 document 中的哪些字段。
  Object类型的时,格式如:{name: 1, _id: 0},为0表示不填充,为1时表示填充。
  String类型的时,格式如:"name -_id",用空格分隔字段,在字段名前加上-表示不填充。详细语法介绍query-select

model
  类型:Model,可选,指定关联字段的 model,如果没有指定就会使用Schemaref

match
  类型:Object,可选,指定附加的查询条件。

options
  类型:Object,可选,指定附加的其他查询选项,如排序以及条数限制等等。

  • 填充Userposts字段:
 
User.findOne({name: 'aikin'}) .exec(function(err, doc) { var opts = [{ path : 'posts', select : 'title' }]; doc.populate(opts, function(err, populatedDoc) { console.log(populatedDoc.posts[0].title); // post-by-aikin }); });
Unity MQTT通信实战:基于HslCommunication.dll实现物联网数据高效传输 在物联网与工业互联网应用中,实时可靠的数据通信是核心需求。MQTT协议作为一种轻量级的发布/订阅消息传输协议,以其低带宽消耗、高实时性和解耦特性,成为设备与云端、软件系统间通信的事实标准。其工作原理基于主题(Topic)过滤,发布者将消息发送至代理服务器(Broker),订阅者按需接收,实现了高效的一对多广播与低延迟数据推送。这一技术为数字孪生、实时监控、多端协同等场景提供了理想的通信基础。在Unity引擎中集成MQTT能力,传统方案或面临开发复杂度高、兼容性问题,或存在商业授权限制。HslCommunic 阅读详情

相关推荐

Unity开发中MonoBehaviour的正确创建方式与生命周期管理

Unity游戏开发中,组件化架构是核心设计模式。MonoBehaviour作为Unity组件的基类,其生命周期由引擎统一管理,包括Awake、Start、Update等方法的自动调用。理解组件与GameObject的绑定机制对于编写健壮代码至关重要,这涉及到引擎底层的对象管理与属性绑定原理。在工程实践中,正确创建MonoBehaviour组件能确保脚本正常参与物理模拟、渲染管线等引擎功能,避免出现空引用异常和生命周期失效问题。常见的应用场景包括角色控制、UI交互、物理特效等游戏元素的实现。本文通过分析Mo

weixin_30432579的博客 389

Unity 虚拟仿真实验中设计模式的使用 ——工厂模式Factory Pattern

工厂模式Factory Pattern) 能把对象的创建逻辑封装起来,让系统更灵活、可扩展。

curry丶的博客 617

C# WinForms俄罗斯方块开发实战:从游戏循环到碰撞检测的完整实现

游戏开发的核心在于对实时状态和交互逻辑的精确管理,其基础原理通常围绕游戏循环、状态机与碰撞检测展开。游戏循环作为驱动引擎,通过定时器或帧更新机制协调逻辑与渲染;碰撞检测则是确保游戏世界物理规则可信的关键算法,涉及边界判断与对象交互。这些技术的工程价值在于构建稳定、可预测的交互体验,是开发各类2D游戏、模拟应用乃至交互式工具的基础。在C# WinForms这样的桌面GUI框架中,实现一个经典游戏如俄罗斯方块,能系统性地实践这些概念:通过模型-视图分离架构管理游戏板与方块状态,利用Graphics进行图形绘制,

weixin_30572613的博客 307

C++设计模式实践:单例与工厂模式深度解析

设计模式是软件工程中解决特定问题的经典方案,通过提供可复用的设计模板提升代码质量。创建型模式中的单例模式确保类只有一个实例并提供全局访问点,常用于配置管理、日志系统等场景;工厂模式封装对象创建过程,实现客户端代码与具体类的解耦,特别适用于跨平台UI、插件系统等需要灵活创建对象的场景。现代C++通过Magic Static特性简化了线程安全单例的实现,而lambda表达式则为工厂模式提供了更简洁的替代方案。合理运用这些模式能显著提升代码的可维护性和扩展性,但需警惕过度设计带来的复杂性。本文结合分布式系统和游戏

weixin_33997389的博客 415

设计模式---工厂模式(DesignPattern_FactoryMethod)

摘录自:设计模式与游戏完美开发 十年磨一剑,作者将设计模式理论巧妙地融入到实践中,以一个游戏的完整实现呈现设计模式应用及经验的传承 《轩辕剑》之父——蔡明宏、资深游戏制作人——李佳泽、Product Evangelist at Unity Technologies——Kelvin Lo、信仁软件设计创办人—— 赖信仁、资深3D游戏美术——刘明恺 联合推荐全书采用了整合...

su9257的博客 127

Unity面试必备:设计模式实战解析与高频考点精讲

设计模式是解决软件设计中常见问题的可复用方案模板,其核心在于通过封装变化、降低耦合来提升代码的可维护性与扩展性。理解其原理对于构建健壮、高效的软件架构至关重要,尤其在游戏开发这类对性能、实时性和模块化要求极高的领域,设计模式能显著提升工程实践水平。在Unity开发中,面对对象生命周期管理、模块通信、状态切换等高频场景,合理运用创建型、结构型和行为型模式,如单例模式、观察者模式和状态模式,可以有效解决资源管理、解耦和复杂行为控制等实际问题。本文聚焦Unity面试中的设计模式考察,结合实战案例与避坑指南,系统梳

weixin_30553777的博客 434

Unity原型模式实战:从Prefab克隆到对象池优化

在软件工程中,创建型设计模式旨在解决对象创建过程中的复杂性与效率问题。原型模式(Prototype Pattern)的核心原理是通过复制现有实例来生成新对象,而非每次都重新执行昂贵的初始化过程。这一模式的技术价值在于它能显著降低创建复杂对象的成本,并支持运行时动态配置,尤其适用于需要批量生成相似但存在差异对象的场景。在Unity游戏开发中,GameObject的实例化与Prefab系统天然契合原型模式的思想。通过将Prefab作为原型模板,并结合ScriptableObject进行数据驱动配置,开发者可以构

dianning8393的博客 423

Behaviac游戏AI框架架构演进与设计哲学深度解析

当我们探讨现代游戏AI开发时,一个核心问题浮现:如何在保证性能的同时,实现复杂行为的灵活组合?另一个关键挑战是,如何在数据驱动与代码控制之间找到最佳平衡点?behaviac框架通过其独特的架构设计,为这些技术难题提供了创新性的解决方案。 将behaviac比作一个**行为交响乐团**的指挥系统再合适不过。在这个系统中,每个AI实体(Agent)如同乐团中的乐器演奏者,行为树(Behavior T

gitblog_00570的博客 919

3d游戏设计 Homework4

3d游戏设计Homework4 这次的作业是实现一个UFO打飞碟游戏,游戏的内容就是可以通过鼠标点击飞碟增加分数,游戏关卡分为3个round,不同round的难度不同,出现的飞碟种类也不同,可以通过FirstSenceControll自定义可编辑组件中的Upper Limit of Difficulty来设定游戏的上限。 游戏截图 代码在https://github.com/hack...

weixin_39011425的博客 509

C#单例模式进阶:基于泛型与反射的通用基类设计与自动初始化

单例模式是软件设计中确保类仅有一个实例并提供全局访问点的经典创建型模式,其核心原理在于控制实例化过程并维护静态引用。在C#等现代语言中,该模式的技术价值体现在管理全局状态、共享资源(如配置、连接池)及服务定位,广泛应用于桌面应用、服务后台及游戏开发等场景。传统实现常面临代码重复与初始化管理难题,而结合泛型约束与反射机制,可构建通用基类实现自动发现与懒加载。本文聚焦于利用Lazy<T>保障线程安全,并通过程序集扫描实现零配置依赖管理,为构建轻量级IoC容器提供实践参考。

weixin_33796205的博客 412

ASP.NET Core开发实战:从入门到精通

ASP.NET Core作为微软推出的开源跨平台Web开发框架,采用模块化设计和中间件管道架构,显著提升了Web应用的性能和可扩展性。其核心原理基于依赖注入系统和轻量级HTTP服务器Kestrel,支持Windows、Linux和macOS多平台部署。在技术价值方面,ASP.NET Core的高性能特性使其请求处理能力可达Node.js的5倍,配合灵活的配置系统和强大的路由功能,特别适合构建现代化Web应用和微服务架构。实际应用场景涵盖电商平台、企业级应用和高并发API服务,通过内置的依赖注入容器和中间件管

weixin_34184561的博客 352

设计模式精讲】3.统一建模语言(UML)速览

【摘要】:同一段设计,有人用两百条群消息仍说不清,有人用一张图五分钟达成共识。UML 的价值不是把系统画得复杂,而是选择合适视角,准确回答“有哪些角色”“谁依赖谁”“运行时谁先调用谁”“对象经历哪些状态”。本文以 Mermaid 为绘图工具,介绍类图、序列图、状态机图、用例图和活动图,重点讲透前三种。类图部分不再把不同关系硬排成一条强弱链,而是区分使用与整体关系、类型关系,并给出与 C++ 所有权和多态机制一致的代码;随后用订单事件和订单生命周期演示时序与状态表达,最后总结选图方法和常见误区。

码工许师傅 459

设计模式精讲】4.单例模式(Singleton)

【摘要】:全局配置、日志器、线程池,这类对象在整个进程里只需要一份。多数人的第一反应是定义一个全局变量,随后便陷入初始化顺序失控、重复构造、多线程竞争的泥潭。本文从全局变量的三宗罪讲起,给出单例模式的意图与结构;重点拆解 C++ 中线程安全单例的三种写法——Meyers’ Singleton、双检锁的坑与修正、std::call_once,并比较它们的行为差异。文章最后讨论单例的代价与替代方案,提醒读者:单例是受限的全局状态,能少用就少用。

码工许师傅 502

第14章 设计模式入门:单例、工厂、建造者与代理

设计模式是"在特定场景下反复被验证的解决方案"。创建型(怎么创建对象:单例、工厂、建造者)、结构型(怎么组合类与对象:代理、装饰器)、行为型(怎么分配职责、怎么协作:观察者、策略)。本章主角是创建型 3 个 + 结构型 1 个(代理)+ 行为型 1 个(观察者)。设计模式解决的典型痛点:代码重复、难以修改、到处 new 导致耦合(耦合指类与类之间依赖太深,改一个要动一片)。// 反面教材:创建"形状"的逻辑散落在各处,每处都要写一遍 if-elseSystem.out.println("画一个圆")

成熟的标题 237

设计模式在 JS 中的应用:用 TS 重写经典模式,结合 React / Vue 真实业务场景

删除

2603_94941287的博客 273

设计模式精讲】14.外观模式(Facade)

把一份源文件编译成中间码,本是一行需求;直接调用子系统,却变成五步固定仪式——预处理器、词法器、语法器、语义检查、IR 生成各有接口与状态,每个调用方都要背下组装顺序。本文从编译器前端的编排成本讲起,给出外观模式的 GoF 意图与「只编排、不决策」的定性,辨析它简化调用而非隐藏扩展点;现代 C++ 部分讲 PIMPL 编译防火墙与外观的正交叠加、分层「附加外观」对上帝对象的防御。文末对照 std::filesystem、POCO Crypto 对 OpenSSL 的门面化、Abseil 的命令行解析与 AO

码工许师傅 439

软考 系统架构设计师历年真题集萃(332)—— 2026年5月系统架构设计师真题25

软考 系统架构设计师历年真题集萃(332)—— 2026年5月系统架构设计师真题25

phmatthaus的专栏 61

设计模式精讲】12.组合模式(Composite)

统计一个目录占多少空间,听起来是道算术题,写成代码却是一场类型审判——每个节点先问「你是文件还是目录」,文件加字节、目录开循环,递归里塞满分支。本文从备份工具的体积统计讲起,给出组合模式的 GoF 意图:把叶子和容器编进同一个接口的树形结构,让客户端「不必知道自己拿到的是哪一个」;C++ 实现覆盖裸指针级联释放的传统版、unique_ptr 持子树的现代版、以 walk 内遍历挂接新操作的扩展法。文末对照 Boost.PropertyTree、POCO 的 XML DOM 与 AOSP 的控件树。读完你能让

码工许师傅 297
上一篇: nodejs中的underscore.js
下一篇: NodeJs中庸node-inspector调试
hellochenlu
博客等级 码龄14年 97粉丝 184原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值