GVKun编程网logo

Node.js环境下对MongoDB实现查,插,分页功能(mongodb分页插件)

6

本文将介绍Node.js环境下对MongoDB实现查,插,分页功能的详细情况,特别是关于mongodb分页插件的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉

本文将介绍Node.js环境下对MongoDB实现查,插,分页功能的详细情况,特别是关于mongodb分页插件的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于mongodb初始化并使用node.js实现mongodb操作封装方法、MongoDB实现查询、分页和排序操作以及游标的使用、Node(九)之Node配合MongoDB实现简单的注册登录、node+express+MongoDB实现小商城服务端的知识。

本文目录一览:

Node.js环境下对MongoDB实现查,插,分页功能(mongodb分页插件)

Node.js环境下对MongoDB实现查,插,分页功能(mongodb分页插件)

写法上还是模块化,尽量把不同职责的代码分开,避免"万能类",尽量采用MVC。

连接,创建数据库,插入数据

  db.js:

  

//这个模块里面封装了所有对数据库的常用操作

var MongoClient = require('mongodb').MongoClient;

//不管数据库什么操作,都是先连接数据库,所以我们可以把连接数据库
//封装成为函数

function _connectDB(callback) {
    var url = "MongoDB://127.0.0.1/haha";
    MongoClient.connect(url,function (err,db) {
        if(err) {
            callback(err,null);
            return;
        }
        callback(err,db);
    });
}

exports.insertOne = function (collectionName,json,callback) {
    _connectDB(function (err,db) {
            if(err) {
                callback(err,null);
                return;
            }
            db.collection(collectionName).insertOne(json,result) {
                callback(err,result);
                db.close();//关闭数据库
            })
        });
}

exports.find = function (collectionName,callback) {
    var result = [];   //结果数组
    if(arguments.length != 3) {
        callback("find函数接受三个参数",null);
        return ;
    }
    //链接数据库,链接之后查找所有
    _connectDB(function (err,db) {
        var cursor = db.collection(collectionName).find(json);
        cursor.each(function (err,doc) {
            if(err) {
                callback(err,null);
                return;
            }
           if(doc != null) {
               result.push(doc); //放入结果数组
           }else {
               //遍历结束,没有更多的文档
                callback(null,result);
           }
        });
    });
}

01.js:

var express = require("express");
var app = express();
var MongoClient = require('mongodb').MongoClient;

app.get("/",function (req,res) {
    //url就是数据库地址,/表示数据库
    //假如数据库不存在,没有关系,程序会帮你自动创建一个数据库
    var url = "mongodb://localhost:27017/haha";
    //连接数据库
    MongoClient.connect(url,function(err,db) {
        //回调函数表示链接成功做的事情,db参数就是连接上的数据库实体
        if(err) {
            console.log("数据库连接失败");
            return ;
        }
        console.log("连接数据库成功");
        //插入数据,集合如果不存在,也没有关系,程序会帮你创建
        db.collection("student").insertOne({
            "name" : "哈哈","age" : parseInt(Math.random()*100 + 10)
        },result) {
            if(err) {
                console.log("插入失败");
                return ;
            }
            console.log("插入成功");
            console.log(result);
            res.send(result);
            db.close();
        });
        db.close();
    });
});

app.listen(3000);

 

1版本分页

  在db.js这种版本的分页效率是比较低的,因为已经查询了所有数据库,然后筛选需要push进数组。

02.js:

var express = require("express");
var app = express();
var db = require("./model/db.js");

app.get("/",res) {
    db.insertOne("teacher",{"name":"小红"},result) {
        if(err) {
            console.log("插入失败");
        }
        res.send("插入成功");
    });
});

app.get("/du",res) {
    //这个页面现在接受一个page参数。
    var page = parseInt(req.query.page); //express中读取get参数很简单
    var a = [];
    db.find("student",{},result) {
        //这是一种分页查询的笨方法,效率低,因为已经查询了所有数据库,然后再回调里面筛选
        for(var i = 10 * page; i < 10*(page + 1); i++ ) {
            a.push(result[i]);
        }
        res.send(a);
    });
});

app.listen(3000);

2版本分页

利用mongodb自带的函数limit()和skip(),重写db2.js,实现分页,但是这两个函数底层是怎么实现的呢,据说效率蛮高,底层实现这里暂时先不探究,日后专门开一篇来探讨。

//优化后,加入skip,limit参数的写法
//这个模块里面封装了所有对数据库的常用操作

var MongoClient = require('mongodb').MongoClient;

不管数据库什么操作,都是先连接数据库,所以我们可以把连接数据库封装成为函数

function _connectDB(callback) {
    var url = "MongoDB://127.0.0.1/haha";
    MongoClient.connect(url,function (err,db) {
        if(err) {
            callback(err,255)">null);
            return;
        }
        callback(err,db);
    });
}

exports.insertOne = function (collectionName,callback) {
    _connectDB(if(err) {
                callback(err,255)">null);
                return;
            }
            db.collection(collectionName).insertOne(json,result);
                db.close();关闭数据库
            })
        });
}

exports.find = var result = [];   结果数组
    JS没有函数重载,只能手动实现
    if(arguments.length == 3) {
       如果没有传args
        那么参数C就是callback,参数D没有传。
        var callback = C;
        var skipnumber = 0;
        数目限制,limit(0)就是没有限制
        var limit = 0;
    }else if(arguments.length == 4) {
        var args = C;
        var callback = D;
        应该省略的条数
        var skipnumber = args.pageamount * args.page;
        数目限制
        var limit = args.pageamount;
    }else {
        throw new Error("find函数的参数个数,必须是3个,或者4个");
        return;
    }
    从第零页开始
    console.log("略过了"+skipnumber+"条"+"限制在"+limit+"条");
    链接数据库,链接之后查找所有
    _connectDB(var cursor = db.collection(collectionName).find(json).skip(skipnumber).limit(limit);
        cursor.each(return;
            }
           if(doc != null) {
               result.push(doc); 放入结果数组
           }else {
               遍历结束,没有更多的文档
                callback(null,result);
           }
        });
    });
}

03.js:

因为原生js没有函数重载,注意这里还手动对函数根据参数个数不同进行了重载,尽量让程序健壮。注释很详细了。

总结

以上是小编为你收集整理的Node.js环境下对MongoDB实现查,插,分页功能全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

mongodb初始化并使用node.js实现mongodb操作封装方法

mongodb初始化并使用node.js实现mongodb操作封装方法

mongodb的下载只要在https://www.mongodb.com/网站就能够下载

或者使用本地下载 https://www.jb51.net/softs/590664.html

下载后安装只用一直点next就可以,注意最好使用默认路径安装到C盘,然后在任意位置建立一个文件夹用于储存你的数据库

这里我命名的是mongodbWorkspace

复制他的路径,在命令行工具(windows快捷键win+R)中,输入mongod --dbpath 你的路径,我的如下所示

现在你就已经初始化好了你的数据库,不用关掉它,他打开来才是开启了数据库服务,然后再新建一个命令行工具窗口

输入mongo,若出现以下窗口,代表你的连接已经成功了,这里是能够写操作mongodb的代码的

输入use yourDatabaseName =>如果你有这个数据库名,则进入,如果没有这个数据库名,则新建了这个数据库

现在我打开了我的VScode,新建一个终端后输入npm installmongodb下载完成后,在index.js中导入(后面会有代码)

先定义一个用于储存方法的JS文件,我命名为myFun.js,内容如下

myFun.js

//传入db环境, 集合名字,需要插入的数据,callback
var insertData = function (db, myCollection, data, callback) {
  //获得指定的集合 
  var collection = db.collection(myCollection);
  //插入数据
  collection.insert(data, function (err, result) {
    //如果存在错误
    if (err) {
      console.log(''Error:'' + err);
      return;
    }
    //调用传入的回调方法,将操作结果返回
    callback(result);
  });
}
//传入db环境, 集合名字,要修改的数据的条件,要修改的结果,callback
var updateData = function (db, myCollection, where, set, callback) {
  //获得指定的集合 
  var collection = db.collection(myCollection);
  //修改数据
  collection.updateMany(where, set, function (err, result) {
    //如果存在错误
    if (err) {
      console.log(''Error:'' + err);
      return;
    }
    //调用传入的回调方法,将操作结果返回
    callback(result);
  });
}
//传入db环境, 集合名字,要查询的数据的条件,要显示的字段,callback
var findData = function (db, myCollection, where, set, callback) {
  //获得指定的集合 
  var collection = db.collection(myCollection);
  //查询数据
  collection.find(where, set).toArray(function (err, result) {
    //如果存在错误
    if (err) {
      console.log(''Error:'' + err);
      return;
    }
    //调用传入的回调方法,将操作结果返回
    callback(result);
  });
}
//传入db环境, 集合名字,要删除数据的条件,callback
var deleteData = function (db, myCollection, where, callback) {
  //获得指定的集合 
  var collection = db.collection(myCollection);
  collection.remove(where, function (err, result) {
    //如果存在错误
    if (err) {
      console.log(''Error:'' + err);
      return;
    }
    //调用传入的回调方法,将操作结果返回
    callback(result);
  });
}


//暴露方法
module.exports.insertData = insertData;
module.exports.updateData = updateData;
module.exports.findData = findData;
module.exports.deleteData = deleteData;

最后的几行是用来暴露内部方法的,在你的index.js中可以require这个JS文件,然后就能访问到内部的数据及方法

这里是按照我的想法来定义的,这里只是一个示例,大家最好能按照自己的想法来设计自己的方法,会使用的更加舒服,比如myCollection可以传进来他的集合名字,也可以传进来的是这个集合名字的实例,这样会对自己有很大的提升,下面是我的主JS文件

index.js

var MongoClient = require(''mongodb'').MongoClient;
var myFun = require(''./myFun'');

//定义连接数据库的地址
const url = ''mongodb://localhost:27017/'';
var dbName = ''kejikeji''

//连接数据库
MongoClient.connect(url, (err, client) => {
  if (err) {
    console.log(''数据连接失败'');
    return false;
  }
  console.log(''数据库连接成功'');
  let db = client.db(dbName);  /*获取db对象*/
  let collection = "user";
  var data = [{ "name": "mongodb3.0", "age": 114 }, { "name": "mongodb3.0", "age": 17 }];
   myFun.insertData(db, collection, data, (result) => {
     console.log(result.ops);
   });
  //要修改数据的条件,>=10岁的用户
  var updateWhere = { age: { "$gte": 10 } };
  //要修改的结果
  var updateSet = { $set: { age: 95 } };
  myFun.updateData(db, collection, updateWhere, updateSet, (result) => {
    console.log(result.result);
  });
  //要查询数据的条件,>=10岁的用户
  var findWhere = { age: { "$gte": 10 } };
  //要显示的字段
  var findSet = { age: 1 };
  myFun.findData(db, collection, findWhere, findSet, (result) => {
    console.log(result[1].age);
  });
  //要删除数据的条件,name=mongodb3.0的用户删除
  var deleteWhere = { name: "mongodb3.0" };
  myFun.deleteData(db, collection, deleteWhere, (result) => {
    console.log(result);
  });
})

这是我的运行截图,代表操作都正确了,在第二个操作窗口,大家可以use进入数据库中,输入db.yourCollectionName.find()查询此集合内的全部字段

这样就能确定自己的语句有没有起作用了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • go嵌套匿名结构体的初始化详解
  • 在django-xadmin中APScheduler的启动初始化实例
  • django初始化数据库的实例
  • Go语言创建、初始化数组的常见方式汇总
  • go语言的初始化顺序,包,变量,init详解

MongoDB实现查询、分页和排序操作以及游标的使用

MongoDB实现查询、分页和排序操作以及游标的使用

一、Find查询

事前准备:插入如下数据

db.Students.insert([
{ _id:1,  name:"Zhao", age:25, country:"USA", books:["JS","C++","EXTJS","MONGODB"]},
{ _id:2, name:"Qian",age:22, country:"USA", books:["PHP","JAVA","EXTJS","C++"]},
{ _id:3,name:"Sun",age:26, country:"USA", books:["JS","JAVA","C#","MONGODB"]},
{ _id:4, name:"Li",age:27,country:"China",books:["JS","JAVA","EXTJS","MONGODB"]},
{ _id:5,name:"Zhou", age:30,country:"China",books:["JS","C#","PHP","MONGODB"]},
{ _id:6, name:"Wu", age:27, country:"Japan", books:["JS","JAVA","C++","MONGODB"]},
{ _id:7, name:"Zheng", age:27, country:"UK", books:["JS","JAVA","EXTJS","PHP"]},
{ _id:8, name:"Wang", age:26,  country:"Korea",books:["JS","C#","EXTJS","MONGODB"]}
]) 

1.指定返回的键

db.[文档名].find ({条件},{键指定})

查询出所有数据的指定键(name ,age ,country)

db.Students.find({},{name:1,age:1,country:1,_id:0})
  • ※条件不写就是查询全部
  • ※需要查询的就在键后指定为1,不用就指定为0(感觉只要想查的键后面有值不见得非得是1)
  • ※如果不指定显示=式_id:0,那查询过程都是带有_id的

2.查询条件

比较操作符

意义

举例

$lt

<

查询出id小于5的学生

> db.Students.find({_id:{$lt:5}},{})

$lte

<=

查询出年龄小于等于25岁之间的学生

> db.Students.find({age:{$lte:25}},{})

$ne

!=

查询出国家不是中国的学生

> db.Students.find({country:{$ne:"China"}},{})

$gt

>

查询所有年纪大于27岁的,中国学生名字

> db.Students.find({age:{$gt:27}},{name:1,country:1,age:1})

{ "_id" : 5, "name" : "Zhou", "age" : 30, "country" : "China" }

$gte

>=

同上

3.包含或不包含

较操作符

意义

举例

$in

包含

查询国家是中国和美国的学生

> db.Students.find({country:{$in:["China","USA"]}},{})

$nin

不包含

查询年龄不是27岁的学生

> db.Students.find({age:{$nin:[27]}},{})

4.OR查询

较操作符

意义

举例

$or

包含

查询年龄小于27岁,或者国家是美国的学生

>db.Students.find({$or:[{age:{$lt:27}},{country:"USA"}]},{})

查询年龄大于等于30岁,或者国家是不是美国的学生

>db.Students.find({$or:[{age:{$gte:30}},{country:{$nin:["China"]}}]},{})

5.Null

为所有美国学生添加性别属性为男性(M)

> db.Students.update({country:"USA"},{$set:{sex:"M"}},false,true)

查询所有sex属性为null的学生

> db.Students.find({sex:{$in:[null]}},{name:1,country:1})

6.正则查询

查询出名字中存在”Zh”的学生的信息

> db.Students.find({name:/Zh/},{})
{ "_id" : 1, "name" : "Zhao", "age" : 25, "country" : "USA", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ], "sex" : "M" }
{ "_id" : 5, "name" : "Zhou", "age" : 30, "country" : "China", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : 7, "name" : "Zheng", "age" : 27, "country" : "UK", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }

7.$not的使用

※$not和$nin的区别是$not可以用在任何地方儿$nin是用到集合上的

查找出名字中不存在“Zh”的学生信息

> db.Students.find({name:{$not:/Zh/}},{})
{ "_id" : 2, "name" : "Qian", "age" : 22, "country" : "USA", "books" : [ "PHP","JAVA", "EXTJS", "C++" ], "sex" : "M" }
{ "_id" : 3, "name" : "Sun", "age" : 26, "country" : "USA", "books" : [ "JS", "JAVA", "C#", "MONGODB" ], "sex" : "M" }
{ "_id" : 4, "name" : "Li", "age" : 27, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : 6, "name" : "Wu", "age" : 27, "country" : "Japan", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "_id" : 8, "name" : "Wang", "age" : 26, "country" : "Korea", "books" : [ "JS","C#", "EXTJS", "MONGODB" ] }

8.数组查询$all和index应用

查询所有拥有JS和PHP书籍的同学

> db.Students.find({books:{$all:["JS","PHP"]}},{})
{ "_id" : 5, "name" : "Zhou", "age" : 30, "country" : "China", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : 7, "name" : "Zheng", "age" : 27, "country" : "UK", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }

查询第三本书是C#的同学

> db.Students.find({"books.2":"C#"},{})
{ "_id" : 3, "name" : "Sun", "age" : 26, "country" : "USA", "books" : [ "JS", "JAVA", "C#", "MONGODB" ], "sex" : "M" } 

上面那个使用index来查询的例子中,"books.2"一定要用""包含起来

9.查询指定长度数组$size

它不能与比较查询符一起使用(这是弊端)

插入一条book数组有两本数的同学

> db.Students.insert({_id:9,name:"Xu",age:26,country:"Japan",books:["C#","PHP"]})
WriteResult({ "nInserted" : 1 })

查询只有两本书的同学

> db.Students.find({books:{$size:2}},{})
{ "_id" : 9, "name" : "Xu", "age" : 26, "country" : "Japan", "books" : [ "C#", "PHP" ] }

查询名字是“Li”的喜欢的书的数量

> var person = db.Students.find({name:"Li"})
> while(person.hasNext()){ obj = person.next(); print(obj.books.length) }

10.$slice操作符返回文档中指定数组的内部值

查询名字为“Wang”书架中第1~3本书

> db.Students.find({name:"Wang"},{books:{$slice:[0,3]}})
{ "_id" : 8, "name" : "Wang", "age" : 26, "country" : "Korea", "books" : [ "JS", "C#", "EXTJS" ] }

查询出最后一本书

> db.Students.find({name:"Wang"},{books:{$slice:-1}})
{ "_id" : 8, "name" : "Wang", "age" : 26, "country" : "Korea", "books" : [ "MONGODB" ] } 

11.文档查询

添加一个对象数组到“Li”同学,记录“Li”同学的成绩

> var li = [{
 
... subject :"Math",
 
... score: 90
 
... },{
 
... subject :"English",
 
... score:85
 
... },{
 
... subject :"History",
 
... score:95
 
... }]
 
> db.Students.update({name:"Li"},{$set:{school:li}})
 
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.Students.find({name:"Li"},{})
 
{ "_id" : 4, "name" : "Li", "age" : 27, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ],
 
 "school" : [{ "subject" : "Math", "score" : 90 },{ "subject" : "English", "score" : 85 }, { "subject" : "History", "score" : 95 }]
}
 
>

查询参加了数学考试,并且分数为90的同学

①.绝对匹配可以

> db.Students.find({school:{subject:"Math",score:90}},{_id:0,name:1})
{ "name" : "Li" }  

但是问题存在如下:

条件顺序变化时候,

> db.Students.find({school:{score:90,subject:"Math"}},{_id:0,name:1})
> --查不到东西--

条件数目不一致的时候,也同样查不到

②.为了解决顺序的问题我可以用对象“.”

> db.Students.find({"school.subject":"Math","school.score":90},{name:1})
{ "_id" : 4, "name" : "Li" }

这种方式支持顺序的变化,但是也同样存在问题,那就是匹配的问题,条件不是作为一对条件来进行匹配的

例如:

> db.Students.find({"school.subject":"Math","school.score":85},{name:1})
{ "_id" : 4, "name" : "Li" } 

这里的85分是英语成绩

③.正确做法单条条件组查询$elemMatch

> db.Students.find({school:{$elemMatch:{subject:"Math",score:90}}},{name:1})
{ "_id" : 4, "name" : "Li" }
> db.Students.find({school:{$elemMatch:{score:90,subject:"Math"}}},{name:1})
{ "_id" : 4, "name" : "Li" }
> db.Students.find({school:{$elemMatch:{subject:"Math"}}},{name:1})
{ "_id" : 4, "name" : "Li" }
>

二、分页与排序

1.Limit返回指定的数据条数

查询出Student文档中前5条数据

> db.Students.find().limit(5)
 

2.Skip返回指定数据的跨度

查询出persons文档中3~8条的数据

> db.Students.find().limit(5).skip(2)

3.Sort返回按照年龄排序的数据[1,-1]

查询所有数据,按照年龄排序

正序

> db.Students.find({},{_id:0,age:1,name:1}).sort({age:1})
{ "name" : "Qian", "age" : 22 }
{ "name" : "Zhao", "age" : 25 }
{ "name" : "Sun", "age" : 26 }
{ "name" : "Wang", "age" : 26 }
{ "name" : "Xu", "age" : 26 }
{ "name" : "Wu", "age" : 27 }
{ "name" : "Zheng", "age" : 27 }
{ "name" : "Li", "age" : 27 }
{ "name" : "Zhou", "age" : 30 }

倒序

> db.Students.find({},{_id:0,age:1,name:1}).sort({age:-1})
{ "name" : "Zhou", "age" : 30 }
{ "name" : "Wu", "age" : 27 }
{ "name" : "Zheng", "age" : 27 }
{ "name" : "Li", "age" : 27 }
{ "name" : "Sun", "age" : 26 }
{ "name" : "Wang", "age" : 26 }
{ "name" : "Xu", "age" : 26 }
{ "name" : "Zhao", "age" : 25 }
{ "name" : "Qian", "age" : 22 }
>

skip性能不好,可以采用插入时间的做法来弥补,具体方法如下:

  • 1.在每一个记录后面都加入一个插入时间的键值对
  • 2.每次取数据的时候都把取出的最后一个数据的时间保存下来,再传给下一次查询
  • 3.使用db.persons.find({date:{$gt:日期数值}}).limit(取出的数据数目)比较查询取出要分页的数据

三、游标和其他知识

1.利用游标来查询数据

var  persons = db.persons.find();
while(persons.hasNext()){
obj = persons.next();
      print(obj.name)
 }

2.游标几个销毁条件  

客户端发来信息叫他销毁

游标迭代完毕

默认游标超过10分钟没用也会别清除

3.查询快照

快照后就会针对不变的集合进行游标运动了,看看使用方法.

db.persons.find({$query:{name:”Jim”},$snapshot:true})

为什么用快照,以为MongoDB在进行更新的时候,例如添加一些键值对,那么MongoDB的处理不会在原来的索引位置上进行更新操作,而是会把

更新之后的数据,放在末尾,那么就导致了前后两次进行查询时候相同索引对应不同数据的情况

补充:

高级查询选项

  • $where
  • $query
  • $orderby
  • $maxsan:integer 最多扫描的文档数
  • $min:doc 查询开始
  • $max:doc 查询结束
  • $hint:doc 使用哪个索引
  • $explain:boolean 统计
  • $snapshot:boolean 一致快照

到此这篇关于MongoDB实现查询操作的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • MongoDB数据库条件查询技巧总结
  • MongoDB基础之查询文档
  • 常用的MongoDB查询语句的示例代码
  • 详解MongoDB的条件查询和排序
  • MongoDB查询之高级操作详解(多条件查询、正则匹配查询等)
  • MongoDB多条件模糊查询示例代码
  • MongoDB 查询操作的实例详解
  • MongoDB数据查询方法干货篇
  • MongoDB的查询方法
  • MongoDB的一些常用查询方法

Node(九)之Node配合MongoDB实现简单的注册登录

Node(九)之Node配合MongoDB实现简单的注册登录

附上代码:(较之前的用txt实现的没有什么区别,只是后端用数据库实现了接口功能)

Html:

<!DOCTYPE html>
<html lang="en">

  <head>
    <Meta charset="UTF-8" />
    <Meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <Meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script src="./jquery.js"></script>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      div:nth-child(2) {
        display: none;
      }
      input {
        display: block;
        height: 40px;
        width: 200px;
        margin: 20px auto;
      }
      button:not(#email) {
        display: block;
        height: 30px;
        width: 70px;
        background: lightcoral;
        border: none;
        margin: 0 auto;
      }
      #email {
        display: block;
        height: 30px;
        width: 100px;
        margin: 0 auto;
      }
      ul {
        height: 50px;
        width: 200px;
        background: lightblue;
        margin: 0 auto;
        list-style: none;
      }
      li {
        height: 50px;
        width: 100px;
        float: left;
        text-align: center;
        line-height: 50px;
      }
      li:hover {
        background: lightgreen;
        cursor: pointer;
      }
    </style>
  </head>

  <body>
    <ul>
      <li id="regChange">注册</li>
      <li id="loginChange">登录</li>
    </ul>
    <div id="reg">
      <input type="text" placeholder="邮箱" id="user" />
      <input type="text" placeholder="密码" id="psd" />
      <input type="text" placeholder="验证码" id="sendmail" />
      <button id="email">发送验证码</button> <button id="btn">注册</button>
    </div>
    <div id="login">
      <input type="text" placeholder="用户名" id="loguser" />
      <input type="text" placeholder="密码" id="logpsd" />
      <button id="logbtn">登录</button>
    </div>

    <script>
      //增加监听事件
      btn.addEventListener("click",clickHandler);
      logbtn.addEventListener("click",clickHandler);
      email.addEventListener("click",sendHandler);
      regChange.addEventListener("click",changeHandler);
      loginChange.addEventListener("click",changeHandler);

      function clickHandler(e) {
        if (this.textContent === "注册") {
          //若为空时跳出
          if (!user.value || !psd.value || !sendmail.value) {
            alert("Can't be empty");
            return;
          }
          //点击注册时将邮箱号,密码,验证码传送至后台
          $.get(
            `http://localhost:1024/index/reg?user=${user.value}&psd=${
              psd.value
            }&mail=${sendmail.value}`,function (res) {
              //后台返回的对象,若hasUser为真,说明已有用户名,否则注册成功
              if (res.hasUser) {
                alert("注册失败");
                return;
              } else {
                alert("注册成功~");
              }
              //成功后隐藏注册,显示登录
              reg.style.display = "none";
              login.style.display = "block";
            }
          );
        } else if (this.textContent === "登录") {
          // 同注册,不能为空
          if (!loguser.value || !logpsd.value) {
            alert("Can't be empty");
            return;
          }
          //点击注册时将邮箱号,密码传送至后台
          $.get(
            `http://localhost:1024/index/login?user=${loguser.value}&psd=${
              logpsd.value
            }`,function (res) {
              //后台返回的对象,若isUser为真,说明正确,并跳转至欢迎页,否则失败
              if (res.isUser) {
                alert("登录成功");
                location.href = "./welcome.html";
              } else {
                alert("用户名或密码不正确");
                return;
              }
            }
          );
        }
      }

      function sendHandler(e) {
        //   点击获取验证码后将验证码发送到后端进行比对
        $.get(`http://localhost:1024/index/sendmail?${user.value}`);
      }

      function changeHandler(e) {
        //   点击上方的注册登录切换
        if (e.target.textContent === "注册") {
          reg.style.display = "block";
          login.style.display = "none";
        } else {
          reg.style.display = "none";
          login.style.display = "block";
        }
      }
    </script>
  </body>

</html>

JS部分:同样要用到express框架,cors,nodemailer,并且不需要File System,Path模块

var MongoClient = require("mongodb").MongoClient;//mongoDb模块引入
var mongoDB = "mongodb://localhost:27017/";//初始化地址
const express = require("express"); //引入express框架(需要先下载,官网有教程)
const url = require("url");
const cors = require("cors"); //引入cors模块(解决跨域问题)
const app = express();
const sendMail = require("./send"); //这个模块是发送邮件模块(在我第三篇node文章里有)

app.use(cors());
// 下面的类似于http请求的头文件(另一篇文章有写到http请求,也是注册登录)
app.all("*",function(req,res,next) {
  //设置允许跨域的域名,*代表允许任意域名跨域
  res.header("Access-Control-Allow-Origin","*");
  res.header("Access-Control-Allow-Headers","content-type"); //允许的header类型
  res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS"); //跨域允许的请求方式
  next(); //是否继续向下执行
});

//注册接口
var count = ""; //新建一个空字符存放验证码,可供全局调用
app.get("/index/reg",(req,res) => {
  let search = url
    .parse(req.url)
    .query.split("&")[0]
    .split("=")[1]; //保存前端传来的数据
  let query = url.parse(req.url).query.split("&");
  MongoClient.connect(//连接数据库
    mongoDB,{
      useNewUrlParser: true
    },function(err,db) {
      if (err) {
        throw err;
      }
      console.log("连接成功!");
      var dball = db.db("UserList");
      // 查询邮箱
      dball
        .collection("allUser")
        .find({
          email: search
        })
        .toArray(function(err,result) {
          if (err) {
            console.log(err);
            return;
          }

          function test() {//应用promise执行,若找到该用户,返回正确,反之返回错误
            return new Promise((resolve,reject) => {//若用户邮箱不存在并且验证码正确,则抛出正确,否则抛出错误对象
              if (!result.length && query[2].split("=")[1] === count) {
                resolve({
                  hasUser: false
                });
                //找到后将数据存储至数据库
                dball.collection("allUser").insert(
                  [
                    {
                      email: query[0].split("=")[1],password: query[1].split("=")[1]
                    }
                  ],result) {
                    if (err) {
                      console.log("Error:" + err);
                      return;
                    }
                  }
                );
              } else {//反之抛出错误对象至前端
                reject({
                  hasUser: true
                });
              }
            });
          }
          test()
            .then(data => {
              console.log(data);
              res.send(data);
            })
            .catch(err => {
              console.log(err);
              res.send(err);
            });
        });
    }
  );
});

//登录接口
app.get("/index/login",res) => {
  //保存前端传来的数据
  let query = url.parse(req.url).query.split("&");
  MongoClient.connect(
    mongoDB,db) {
      if (err) {
        throw err;
      }
      console.log("连接成功!");
      var dball = db.db("UserList");
      // 查询是否有该用户
      dball
        .collection("allUser")
        .find({
          email: query[0].split("=")[1]
        })
        .toArray(function(err,result) {
          if (err) {
            console.log(err);
            return;
          }
          function test() {//若用户邮箱和密码符合,则抛出正确,否则抛出错误对象
            return new Promise((resolve,reject) => {
              if (
                result.length &&
                result[0].password === query[1].split("=")[1]
              ) {
                resolve({
                  isUser: true
                });
              } else {
                reject({
                  isUser: false
                });
              }
            });
          }
          test()
            .then(data => {
              console.log(data);
              res.send(data);
            })
            .catch(err => {
              console.log(err);
              res.send(err);
            });
        });
    }
  );
});

//邮箱验证接口
app.get("/index/sendmail",res) => {
  count = ""; //初始化验证码容器
  let Email = url.parse(req.url).query; //获取前端传来的邮箱号
  for (let i = 0; i < 4; i++) {
    count += Math.floor(Math.random() * 10); //生成4个随机数
  }
  sendMail.send(Email,count); //调用邮件发送模块
  res.send(count);
});
//监听服务
app.listen(1024,() => {
  console.log("Server Start~");
});

邮箱的js文件(send.js)

const nodemailer = require("nodemailer");
let obj = {
  transporter: nodemailer.createTransport({
    service: "qq",// 运营商  QQ邮箱 网易//
    port: 465,secure: true,auth: {
      user: "*********@qq.com",//发送方的邮箱
      pass: "*******" // pop3 授权码
    }
  }),send: function(mail,content) {
    mailOptions = {
      from: '"Hello World~" <**********@qq.com>',to: mail,subject: content,text: content,html: "<h1>" + content + "</h1>"
    };
    this.transporter.sendMail(mailOptions,(error,info) => {
      if (error) {
        return console.log(error);
      }
      console.log("Message sent: %s",info.messageId);
    });
  }
};
module.exports = obj;

 

node+express+MongoDB实现小商城服务端

node+express+MongoDB实现小商城服务端

GitHub地址

前端地址:https://github.com/FZliweiliang/wechat-app-mall

服务端地址:https://github.com/FZliweiliang/wechat-app-mall-server

运行环境

CentOS 7.3
node 8.11.0
npm 5.6.0
MongoDB 3.2.7

主要功能

购物车 绑定手机 用户登录 添加商品 推荐商品 商品列表 优惠券 地址管理 上传图片 ...

接口列表:

管理

Name Method Default Description
/v1/admin/delUser get auto 删除用户
/v1/admin/delItem get auto 删除商品
/v1/admin/addItem post auto 添加商品
/v1/admin/addClass post auto 添加分类
/v1/admin/delClass get auto 删除分类
/v1/admin/addClass post auto 添加分类
/v1/admin/addCoupon post auto 添加优惠券
/v1/admin/couponList get auto 所有优惠券
/v1/admin/uploadBanner post auto 上传banner

首页

Name Method Default Description
/v1/home/bannerList get auto 获取banner
/v1/home/getHotList get auto 获取推荐列表
/v1/home/getList get auto 获取列表
/v1/home/getItem get auto 获取详情

订单

Name Method Default Description
/v1/order/set post auto 创建订单
/v1/order/get post auto 获取订单详情
/v1/order/list get auto 订单列表
/v1/order/update post auto 更新订单

微信

Name Method Default Description
/v1/wx/getUser get auto 获取微信用户信息

用户

Name Method Default Description
/v1/user/bindMobile post auto 绑定手机号
/v1/user/addCity post auto 添加地址
/v1/user/editCity post auto 更新地址
/v1/user/defaultCity post auto 设置默认地址
/v1/user/cityList get auto 地址列表
/v1/user/getCoupon post auto 领取优惠券
/v1/user/couponList get auto 获取拥有的优惠

通用

Name Method Default Description
/v1/public/getClassList get auto 获取分类列表

购物车

Name Method Default Description
/v1/order/addCart post auto 加入购物车
/v1/order/cartList get auto 购物车列表
/v1/order/delIetm post auto 删除商品
/v1/order/editCart post auto 编辑购物车

启动方法

node app.js

说明

1、本人也是第一次使用node做一个完整的项目如果有觉得不合理的地方可以在下方留言或者Issues作者会尽快修复

2、本项目适合初学者或者准备自学node的伙伴,本人也是零基础开始写的node

3、如果对你有帮助的话麻烦给作者一个"star"给与支持

今天关于Node.js环境下对MongoDB实现查,插,分页功能mongodb分页插件的分享就到这里,希望大家有所收获,若想了解更多关于mongodb初始化并使用node.js实现mongodb操作封装方法、MongoDB实现查询、分页和排序操作以及游标的使用、Node(九)之Node配合MongoDB实现简单的注册登录、node+express+MongoDB实现小商城服务端等相关知识,可以在本站进行查询。

本文标签:

上一篇node.js安装(nodejs安装及环境配置)

下一篇node.js模块学习(三) http(nodejs的http模块)