NodeJS:树的反序列化
!!不知问啥,cnblog的MarkDown编辑器不好使了。
本文也在我的博客edwardesire.com上,欢迎品尝。
树的反序列化就是将序列数组安装线索组成树结构,今次项目数据库存储决策节点的方式是通过数组进行,每个节点有一个parent_id键直指双亲节点的node_id键,而在前端展示是决策树的结构。这是在比较在MongoDB存储数组的性能和前后台实现难度下决定的(在此呜谢师哥)。
数据库中的文档
先来看看存储在数据库中的数据,后台通过ObjectId找到样例文档。注意这里,如果直接使用.findById(checkId,callback),回调函数得到结果为MongooseDocuments(其子文档都是embedded document类型,这一类型又有许多多余的参数),这个东西不太适合操作。应该需要使用Mongoose的API lean(),此方法得到的是一个javascript objects。javascript的objects相对就容易操作了,亲身经历。
Dtree.findById(checkId).lean().exec( function(err, dtrees){
node_array = dtrees.node_array;
console.log(dtrees);
console.log('node_array: ',node_array);
//nodes node_array 树结构
nodes = arrayToTree(node_array);
//排序
nodes = sortNodes(nodes);
console.log('nodes: ', JSON.stringify(nodes));
}
这里得到的dtrees就是一个纯粹javascript object。
arrayToTree方法
在上节可以看到,我截取了dtrees的node_array作为参数调用方法arrayToTree,参照的是ling凌yue月的文章。首先将数组按升序排序,以便接下来的操作。从数组尾开始,找到它的双亲节点,插入双亲节点的children数组中。最后得到的根节点(node_id===1)就是一颗完整的树。/**
* 将dtree的节点反序列化为树结构
* @function arrayToTree
* @param {Array} node_array dtree文档中的node_array节点数组
* @return {Object Node} temp_array[0] 包含树结构的根节点
*/
var arrayToTree = function(node_array){
var temp_array = node_array;
//将节点数组升序
temp_array.sort(function(a, b){
return a.node_id-b.node_id
});
//节点的children定义为空数组,@TODO 是否可以删除
node_array.forEach(function(node){
node.children = []; //children is Array
});
//从下往上将每个节点添加到父节点的children数组中
var i = 0;
var count = temp_array.length;
for(i = (count - 1); i > 0; i-- ){
if(temp_array[temp_array[i].parent_id - 1] !== null){
var tNode = temp_array[i];
temp_array[tNode.parent_id - 1].children.push(tNode);
}
}
return temp_array[0];
}
sortNodes方法
我们得到的树在结构上还有问题,其每层的节点序号大小事逆序的,也就是说节点1的子节点数组是[node[3], node[4]]。这个细节在传到前台可能会导致展示问题(与需要展示的内容互为镜像)。/**
* 将树的每层子节点排序,递归
* @function sortNodes
* @param {Object Node} nodes 包含树结构的根节点,子节点的顺序为降序
* @return {Object Node} nodes 原物奉还,各子节点数组的顺序为升序
*/
var sortNodes = function(nodes){
if(nodes.children.length > 0){
var i = 0;
for(; i < nodes.children.length; i++){
nodes.children[i] = sortNodes(nodes.children[i]);
}
nodes.children.sort(function(a, b){
return a.node_id-b.node_id
});
}
return nodes;
}
总结
这周工作量看起来很轻松,实际完成起来还是花了不少时间。当然还有一些其他课程的作业也占用了不少时间。树的反序列化可能还有需要改进的地方。洛阳亲友如相问,午夜清风四零零。
Notes:
- Thinking about arrays in mongodb—monglab上一篇关于在MongoDB存储数组文章
NodeJS:树的反序列化的更多相关文章
- NodeJS:树的序列化
本文也在我的博客edwardesire.com上,欢迎品尝. 接着上周的工作,我们把上周反序列得到的dtree对象输出到JSON,再将其序列化后存入MongoDB. 存入文档 先将上次得到的决策树对象 ...
- nodejs - json序列化&反序列化示例
// demo-json.js var obj = { "name": "LiLi", "age": 22, "sex" ...
- [LintCode] Serialize and Deserialize Binary Tree(二叉树的序列化和反序列化)
描述 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉 ...
- Node.js快速入门
Node.js是什么? Node.js是建立在谷歌Chrome的JavaScript引擎(V8引擎)的Web应用程序框架. 它的最新版本是:v0.12.7(在编写本教程时的版本).Node.js在官方 ...
- 学习node.js 第2篇 介绍node.js 安装
Node.js - 环境安装配置 如果愿意安装设置Node.js环境,需要计算机上提供以下两个软件: 一.文本编辑器 二.Node.js二进制安装包 文本编辑器 这将用来编写程序代码. 一些编辑器包括 ...
- Zookeeper原理分析之存储结构ZkDatabase
ZKDatabase在内存中维护了zookeeper的sessions, datatree和commit logs集合. 当zookeeper server启动的时候会将txnlogs和snapsho ...
- BFS (1)算法模板 看是否需要分层 (2)拓扑排序——检测编译时的循环依赖 制定有依赖关系的任务的执行顺序 djkstra无非是将bfs模板中的deque修改为heapq
BFS模板,记住这5个: (1)针对树的BFS 1.1 无需分层遍历 from collections import deque def levelOrderTree(root): if not ro ...
- NodeJS反序列化漏洞利用
原文来自:http://www.4hou.com/web/13024.html node.js是一个服务器端的运行环境,封装了Google V8引擎,V8引擎执行JavaScript速度非常快,性能非 ...
- 02.树的序列化与反序列化(C++)
1.二叉树的序列化 输入的一棵树: //二叉树的先序遍历-序列化 #include <iostream> #include <string> #include <sstr ...
随机推荐
- NC / Netcat - 反弹Shell
原理 实验环境: 攻击机:windows机器,IP:192.168.12.109 受害机:linux机器,IP:192.168.79.1 攻击机:设置本地监听端口2222 C:\netcat>n ...
- Eclipse - FindBugs Plugin 的安装和使用
Eclipse - FindBugs Plugin 的安装和使用 FindBugs is a static analysis tool that examines the classes in se ...
- Segmentation Fault错误原因总结
最近在项目上遇到了Segmentation Fault的错误,一直调试不出来是哪里出了问题,对于刚接触嵌入式的,也不知道该如何去调试一个项目,定位内存问题,纠结了好几天,好阿红整理下自己的思路.从头开 ...
- C# App.config 详解
读语句: String str = ConfigurationManager.AppSettings["DemoKey"]; 写语句: Configuration cfa = ...
- static,this,抽象类,接口和包
1. static 1)静态变量:Java虚拟机为静态变量开辟单独的存储空间,所以所有的对象内部的静态变量在内存中都指向同一个地址,那么不管哪个对象改变这个成员变量,所有对象中该成员变量的值都发生变化 ...
- Codeforces Beta Round #9 (Div. 2 Only)D
短小精悍的代码 dp[i][j] +=dp[k][j-1]*[i-k-1][j-1] i个结点 J层 #include <iostream> #include<cstdio> ...
- 发布 windows 10 universal app 时微软账号验证失败
具体错误:Visual Studio encountered an unexpected network error and can't contact the Microsoft account s ...
- Asp.Net生成RSS方法
一.RSS简介 什么是RSS? RSS是一种网页内容联合格式(web content sydication format). 它的名字是Really Simple Syndication的缩写. RS ...
- 转:MVC3系列:~Html.BeginForm与Ajax.BeginForm
Html.BeginForm与Ajax.BeginForm都是MVC架构中的表单元素,它们从字面上可以看到区别,即Html.BeginForm是普通的表单提交,而Ajax.BeginForm是支持异步 ...
- svn 提交失败 更新失败 提示 已经锁定
出现问题的原因:在上传的时候,由于网络掉线,导致svn提交到一半就没有反应了,这个时候我点击了取消,再之后无论是进行 更新还是提交,都提示 已经锁定 解决方法:在项目的空白地方,点击SVN 清理 ...