Mongodb 数据类型及Mongoose常用CURD

4. lodash合併对象类型数组并去重新

lodash的unionWith方式得以统一三个数组,並且能够让我们提供贰个comparator方法来决定该怎么相比八个数组中的成分是或不是是一致的,以此来决断这些数量是还是不是是重复的。

合英文档对unionWith方法的陈述请看这里:https://lodash.com/docs/4.17.4#unionWith

_.unionWith([arrays], [comparator])

明亮起来也比较轻便,请看代码如下:

const _ = require('lodash');
const orgGaming = [
      {
        "enter": new Date("2017-04-25T14:32:12.081Z"),
        "exit": new Date("2017-04-25T14:48:52.082Z"),
      },
      {
        "enter": new Date("2017-04-26T14:32:12.081Z"),
        "exit": new Date("2017-04-26T14:48:52.082Z"),
      }
]

const newGaming = [
     {
        "enter": 1493130732081,
        "exit": 1493131732082,
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
]

gaming = _.unionWith(orgGaming, newGaming, (value1, value2) => {
    if (typeof value1.enter === 'number' && typeof value2.enter === 'number') {
        return (value1.enter === value2.enter);
    } else if (typeof value1.enter === 'number' && typeof value2.enter === 'object') {
        return (value1.enter === value2.enter.getTime());
    } else if (typeof value1.enter === 'object' && typeof value2.enter === 'number') {
        return (value1.enter.getTime() === value2.enter);
    } else if (typeof value1.enter === 'object' && typeof value2.enter === 'object') {
        return (value1.enter.getTime() === value2.enter.getTime());
    }
});

console.log(gaming);

此地根本的地方正是uionWith,有多少个位置需求小心:

  • 参数的顺序,极其是前四个数组参数。假若第贰个数组中有些成员判断和第2个数组中的某些成员是双重的,那么首先个数组中的该因素会保留,第一个数组中的对应成分会移除。
  • 其多少个参数正是一个回调方法,接受七个参数,其实正是五个需求比对的数组的积极分子,这里大家透过比对四个成员的enter是还是不是等于来判别该成员是还是不是再一次。
  • 看清是或不是再一次的时候,大家须求将日志先转变来unixtime的格式,然后再进行相比。

最终我们得以看到去重新后的输出:

[ { enter: 2017-04-25T14:32:12.081Z,
    exit: 2017-04-25T14:48:52.082Z },
  { enter: 2017-04-26T14:32:12.081Z,
    exit: 2017-04-26T14:48:52.082Z },
  { enter: 1493130735084, 
    exit: 1493131736087 } ]

能够见见,最终输出的列表中唯有三个对象,个中一个重新的早就被撤消掉了。

说起底我们经过mongoose将那份数据存款和储蓄到mongodb时,如前方所述,会自动将unixtime调换到Date实行仓库储存,那样数据就集合起来了。这里mongoose的操作就不赘述了,有意思味的爱人能够团结实施下。

如上便是自己对八个由对象类型组成的数组举办合并的片段品尝和试行,假如大家有更加好更优雅的章程的话,应接在言三语四中给出去。先拜谢了!

本文由世界会湛江分舵编写,转发需授权,喜欢点个赞,作弄请商酌,进一步沟通请关怀公众号techgogogo依然直接挂钩自个儿微信zhubaitian1

前言

1. 主题材料根源


近期在达成二个API,当中有一点意义是内需从Mongodb中抽取一个由Date对象组成的数组,然后将客户端传过来的unixtime合併到该数组中,何况去重新。

比如说,借使从mongodb中取回来的多寡中有一个称作gaming的项,特意用来记录客商步向游玩的开首时间和退出时间。 那么mongoose的schema的定义将大借使那般的:

const DeviceLogSchema = new Schema({
 ...
  gaming: [{ enter: Date, exit: Date, _id: false }],          
 ... 
});

而从mongodb取回来的多少大约正是那一个样子的:

{
"gaming": [
      {
        "enter": 2017-04-25T14:32:12.081Z,
        "exit": 2017-04-25T14:48:52.082Z,
      },
      {
        "enter": 2017-04-26T14:32:12.081Z,
        "exit": 2017-04-26T14:48:52.082Z,
      }
    ],
}

也正是说通过mongoose的model取回来的笔录中,enter和exit都以Date(对mongodb来讲)类型的,而对于js来讲,便是贰个Object(js将装有轻便类型以外的数据类型都管理成Object)。

let deviceLog = await DeviceLog.findOne({});
console.log(typeof deviceLog.enter) // ->Object

而顾客端每隔一段时间就能够调用api来将新的客户游戏时间回传给服务器,但用的格式是unixtime。

{
    "gaming": [{
      "enter": 1493130733081,
      "exit": 1493131734082,
    },{
      "enter": 1493130735084,
      "exit": 1493131736087,
    }],
}

此间的enter和exit的unixtime时间格式,对于js来讲,正是number类型的。

笔者们透过mongoose来保存的时候,无需将unixtime进行别的转变,直接保存, mongoose会将其活动转成Date格式实行保存。也正是说,如果保留前的gaming内容是之类那个样子的:

"gaming": [
      {
        "enter": 2017-04-25T14:32:12.081Z,
        "exit": 2017-04-25T14:48:52.082Z,
      },
      {
        "enter": 2017-04-26T14:32:12.081Z,
        "exit": 2017-04-26T14:48:52.082Z,
      },
      {
        "enter": 1493130733081,
        "exit": 1493131734082,
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
    ],

那正是说通过mongoose的model保存之后,最后会活动成为近乎以下那样的格式:

"gaming": [
      {
        "enter": 2017-04-25T14:32:12.081Z,
        "exit": 2017-04-25T14:48:52.082Z,
      },
      {
        "enter": 2017-04-26T14:32:12.081Z,
        "exit": 2017-04-26T14:48:52.082Z,
      },
      {
        "enter": 2017-04-27T14:22:12.021Z,
        "exit": 2017-04-27T15:32:12.031Z,
      },
      {
        "enter": 2017-04-26T16:22:12.082Z,
        "exit": 2017-04-26T16:52:12.082Z,
      }
    ],

那就是说这里要消除的标题便是:

  • 怎么样将客商端传过来的新数组和从mongodb取回来的数组举办联合
  • 联合时怎么依照游戏步入的小运enter来去重复

当然,我们得以用原始的法子,做两层遍历,分别便利三个例外的数组,然后将里面一个比对数据的类型调换到别的一个数额对应的体系,然后进行比较其是还是不是等于,相等的话就去掉,不想等的话就将数据追加到数组中。

但,那样效能太低了,应该有更好的更优雅的方法来提携我们管理这种主题材料。

上述内容是作者给我们介绍的Mongodb 数据类型及Mongoose常用CU中华VD ,希望大家喜爱。

3. ES6数构成并新特色


实在,借使不是因为要考虑去重新的难点来讲,我们一同能够因此ES6的新特征来完毕的。

array1.push(...array2)

此地的'...'操作符叫做扩充运算符,是ES6引进的新特征。指标是将一个数组打垮成用逗号分隔的参数体系。

const array = [1, 2];
console.log(...array); // 相当于 console.log(1,2)

所以地方的身体力行代码的意味正是将array2打散后,将各样元素作为参数push到array第11中学生成新的数组。所以,如若选择到我们的面貌中的话

const orgGaming = [
      {
        "enter": new Date("2017-04-25T14:32:12.081Z"),
        "exit": new Date("2017-04-25T14:48:52.082Z"),
      },
      {
        "enter": new Date("2017-04-26T14:32:12.081Z"),
        "exit": new Date("2017-04-26T14:48:52.082Z"),
      }
]

const newGaming = [
     {
        "enter": 1493130732081,
        "exit": 1493131732082,
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
]

orgGaming.push(...newGaming);
console.log(orgGaming);

最终将会输出未有去重新的结果:

[ 
  { enter: 2017-04-25T14:32:12.081Z,
    exit: 2017-04-25T14:48:52.082Z },
  { enter: 2017-04-26T14:32:12.081Z,
    exit: 2017-04-26T14:48:52.082Z },
  { enter: 1493130732081, 
    exit: 1493131732082 },
  { enter: 1493130735084, 
    exit: 1493131736087 } 
]

本来,ES6的这一个数组合併格局仍能这么写:

[...array1,...array2]

并且,ES6还提供了对简易数据类型去重新形式:

[...new Set([...array1 ,...array2])];

可是,那些只好针对轻便数据类型举行去重新,举个例子数字类型和字串类型等。

const array1 = ['techgogogo', 'sina', 'baidu'];
const array2 = ['techgogogo', 'google'];
console.log([... new Set([...array1, ...array2])]);

末尾输出:

[ 'techgogogo', 'sina', 'baidu', 'google' ]

但是对于大家那边的目的类型组成的数组,它是做不到的。

最注重的是,它并未有提供一个comparator的回调方法来放大家处理相应怎么着推断,八个数据是不是是重复的。

此处,lodash的数组操作,可能是个正确的缓和方案(之一)。

var mongoose=require('mongoose');
var Schema=mongoose.Schema;
//1、连接字符串
mongoose.connect('mongodb://localhost/test');
//2、定义你的数据模型(也就是我们在关系数据库中定义的Table)
var TodoSchema=new Schema({
  title:String,
  finished:{type:Boolean,default:false},
  post_date:{type:Date,default:Date.now}
});
//3、访问todo对象模型
mongoose.model('Todo',TodoSchema);
//添加
exports.add=function(title,callback){
  var newTodo=new Todo();
  newTodo.title=title;
  newTodo.save(function(err){
    if(err){
      console.log(err);
      callback(err);
    }else{
      callback(null);
    }
  });
}
//查找单独的数据
var findTodoById=exports.findTodoById=function(id,callback){
  Todo.findOne({_id:id},function(err,doc){
    //doc也就是根据id得到的记录值
    if(err){
      callback(err,null);
    }
    callback(null,doc);
  })
}
//删除
exports.delete=function(id,callback){
  exports.findTodoById(id,function(err,doc){
    if(err){
      callback(err);
    }else{
      doc.remove();
      callback(null);
    }
  })
}
//编辑标题
exports.editTitle=function(id,title,callback){
  exports.findTodoById(id,function(err,doc){
    if(err){
      callback(err);
    }else{
      doc.post_date=new Date();
      doc.title=title;
      doc.save(function(err){
        if(err){
          callback(err);
        }else{
          callback(null);
        }
      })
    }
  })
}
exports.allTodos=function(callback){
  Todo.find({},callback);
}
//分页查询
exports.TodoPageList=function(pageIndex,pageSize,callback){
  var m=Todo.find({}); //也有方法直接这样写: var m=this;
  var start=(pageIndex-1)*pageSize;
  m.skip(start);
  m.limit(pageSize);
  m.sort({'post_date','asc'}); //排序
  //根据关键字查询后分页
  //m.where('title','XXX');
  //执行分页查询
  m.exec(function(err,rs){
    //分页后的结果
    if(err){
      callback(err);
    }else{
      Todo.find(function(err,result){
        /*
          一般情况下的分页你需要同时返回数据库记录总数和分页后的数据,所以这里使用了Todo.find再查询一次
        */
        callback({rows:rs,total:result.length});
      });
    }
  })
}

2. 推行数据

这正是说大家就依照上面蒙受的题目,来确立五个实验所用的多寡。三个是表示从mongodb取回来的数据:

const orgGaming = [
      {
        "enter": new Date("2017-04-25T14:32:12.081Z"),
        "exit": new Date("2017-04-25T14:48:52.082Z"),
      },
      {
        "enter": new Date("2017-04-26T14:32:12.081Z"),
        "exit": new Date("2017-04-26T14:48:52.082Z"),
      }
]

一个是顾客端传进来的数目:

const newGaming = [
     {
        "enter": 1493130732081, // 这和orgGamine第一条数据重复
        "exit": 1493131732082, // 这和orgGamine第一条数据重复
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
    ]

新数组中的第一条数据和enter和数据库中的第一条数据的enter,事实上是平等的,所以大家盼望统一之后这几个重复数据是去掉的。

    4、字符串。Mongodb中字符串采取UTF-8编码形式,{"x":"hello world"}。

    7、数据。Mongodb中数组的施用和javascript一样{"x":["hello","world"]}。

    11、二进制。

Mongoose

    10、代码。{"x":function aa(){}}。

什么是MongoDB?

Mongoose是包裹了MongoDB的操作的二个指标模型库,为nodejs而生。就疑似咱们嫌原生javascript难写,代码量多,于是用jQuery库一样,因为MongoDB的操作接口复杂,不人性,所以有了Mongoose。那些库完全部是可选的。
   Mongoose的使用特别简单,在App的package.js中的dependence中加入mongoose,然后 npm install 就可以。

    9、Id和ObjectId()。Mongodb种种文书档案都会蕴藏三个_id,借使您不钦命期Mongodb会自动生成二个ObjectId对象。

 Mongodb数据类型

常见CURD

      看完了Node.js实战,在那之中在多少存款和储蓄部分涉及了Redis、Mongodb,我本身也遵照书中的介绍写了多少个简单的demo,在demo的进度首先遇到的标题正是数据类型和广阔的CUKoleosD写法。 mongodb的广阔操作有三种艺术,贰个是一向运用API,也就一定于您在SQL Server客商端中使用T-SQL编写SQL语句来操作数据一致,其次正是在前后相继中应用mongoose驱动来操作数据,约等于大家在程序里用ADO.NET或EF来操作数据,借使您早已写了多少个调用API的demo,那么本人建议再回过头来看看mongoose的API,多看API,並且记住常见的多少个法子比方where,skip,sort等

     根据过去大家编辑Web方式,大家会关心数据从顾客端(Views)假设到Controller层, 然后把数据怎么样从Controller层传递到Dao层以及那七个层面传递数据时的有个别技艺,那么在Node里这种思维也是适用的。

    5、日期类型。{"x":new Date()}。

   3、数据类型。在Mongodb Shell中暗中同意使用62个人浮点型数据,如{"x":2.32}、{"x":2},如若要采纳整数门类则用{"x":NumberInt(2)}、{"x":NumberLong(2)}。

   1、null。{"x":null}。

   MongoDB 是三个开源的 NoSQL 数据库,比较 MySQL 那样的关系型数据库,它越是轻巧、灵活,极度适合在数据规模异常的大、事务性不强的场馆下使用。 

    8、内嵌文书档案。{"x":{"y":"Hello"}}。

    2、Boolean。{"x":true} 、{"x":false}。

您或然感兴趣的稿子:

  • 行使Mongoose让JSON数据直接插入或更新到MongoDB
  • Node.js的MongoDB驱动Mongoose基本使用教程
  • 关于mongoose连接mongodb重复访谈报错的解决办法
  • MongoDB用Mongoose获得的对象不可能充实属性完美化解措施(二种)

    6、正则表明式。 Mongodb中可应用和javascript一样的正则表明式 {"x":/itbilu/i}。

本文由开元棋牌发布于数据库,转载请注明出处:Mongodb 数据类型及Mongoose常用CURD

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。