soword科技言
永久公益免费API接口
提供永久免费的API接口,查看更多API接口,如果您有其他免费API资源,请联系我们,造福人类。
提供商务开发:小程序,系统,APP
定制开发,免费评估,免费咨询,价格便宜,售后保障,前往开发服务中心联系开发客服中心
完整的MongoDB PWA教程


我一直喜欢向您展示一些实际示例的教程他们有助于了解如何使用代码在生产环境中实际构建应用程序。然后,我可以利用这些知识来建立自己的知识。在本教程中,我们将把世界地理位置 数据存储Mongo集合中

在存储环境中,这可能意味着处理大量数据。这就是数据库的主要用途。它们为您提供了一个界面可以直接从Node.js程序创建读取编辑(更新)删除 大量数据(例如用户数据帖子,评论,地理位置坐标等)

“完整”不是指每个Mongo函数的文档。而是在构建PWA时Mongo代码的实例用作实际示例。

Mongo 集合类似于MySQL数据库中除了在Mongo中,所有内容都存储在类似JSON的对象中(但也使用BSON来存储唯一的_id属性,类似于MySQL存储唯一行键的方式。)

安装Mongo和基本操作

Mac 上的TerminalWindows 10上的bash.exe中,使用ssh root@xx.xxx.xxx.xx登录到远程主机x替换为Web主机IP地址。)然后使用cd导航至例如,远程主机(/ dev / app上的项目目录

安装系统范围的Mongo服务:

须藤apt-get install -y mongodb

-y指令将自动回答“是”将所有的安装问题。

之后,我们需要启动mongo服务(在下一节中说明)。

Mongo Shell。

就像MySQL具有命令行外壳程序一样,我们可以在其中创建表,用户等。Mongo也具有自己的外壳程序来创建集合显示数据库等。

首先,我们需要启动 Mongo服务:

sudo服务mongodb启动

如果您需要停止 mongo服务器,可以执行以下操作:

sudo服务mongodb停止

但不要这样做,我们需要在下一部分中运行该服务!

要输入Mongo shell,请在cli / bash中输入mongo命令:

蒙哥

您将看到bash变为> character。让我们键入use命令来创建一个新的数据库或切换到现有数据库):

>使用用户切换到数据库用户

输入> db以确认我们确实切换到了用户数据库:

>分贝使用者

让我们通过执行show dbs命令来查看所有现有数据库

>显示数据库管理员0.000GB本地0.000GB

即使我们在较早的步骤中创建了用户数据库,该数据库也不在此列表中。为什么?那是因为我们还没有向数据库添加任何集合。这意味着用户实际上已经存在,但是直到添加集合后它才会显示在此列表中。

添加Mongo收藏

让我们用户数据库添加一个新集合请记住,mongo中的集合等效于MySQL 中的

db.users.insert({name:“ felix”})

我们只是将一个集合插入到用户数据库中。

让我们运行>现在显示数据库

>显示数据库管理员0.000GB本地0.000GB用户0.000GB

只需在用户数据库中插入一个类似JSON的对象即可创建一个“ 表”。但是在Mongo中,它只是基于文档的模型的一部分。您可以在该对象中插入更多对象,并像对待MySQL中的 / 一样对待它们

安装Mongo NPM软件包

npm install mongodb-保存

产生数据

在介绍Mongo方法之前,让我们决定要在数据库中存储的内容。让我们看一下世界坐标系它与笛卡尔完全不同。这里的中心点位于尼日利亚拉各斯附近

纬度经度可视化。[0,0]点位于坐标系的中心,轴在负方向上向左和向下移动。HTML5地理位置会根据您的IP地址自动计算您的位置。但是我们仍然需要将其转换为图像上的2D。图片信誉。

前端

收集数据。

HTML5提供出的现成的地理位置,给我们纬度经度,只要客户同意共享这些信息。以下代码将在台式机和移动设备上创建一个弹出消息框,要求用户“允许”共享位置。如果用户同意,它将存储在latlon变量中:

如果(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position){ let lat = position .coords.latitude; let lon = position .coords.longitude;
}}

好吧,这是一个很好的开始。

但这还不够。我们需要将其转换为HTML5 <canvas>理解的2D坐标系。我们需要在地图图像上方绘制位置标记所以我写了这个简单的World2Image函数来解决这个问题:

函数 World2Image(pointLat,pointLon){ const mapWidth = 920;const mapHeight = 468;const x =((mapWidth / 360.0)*(180 + pointLon)));const y =((mapHeight / 180.0)*(90-pointLat));返回 [x,y];}

我们只需将地图图像尺寸分别除以360和180,然后再乘以180 + pointLong90-pointLat即可调整到中心。将纬度/经度转换为2D坐标的最终代码如下所示:

如果(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position){ let lat = position .coords.latitude; let lon = position .coords.longitude; let xy = World2Image(lat,lon); let x = xy [0]; let y = xy [1];
}}

当然,您可以在应用中使用所需的任何数据。我们只需要一个有意义的场景即可为一个潜在的实时日落摄影应用程序演示实际示例

将代码放在PWA中<head>标记内的<script>标记之间最好在里面:window.onload = event => { / *在这里* / };

现在,每次有新访客加入我们的页面时,都会要求他们共享地理位置。一旦他们按下“允许”按钮,它将被收集并存储在latlonxy vars中。然后,我们可以创建Fetch API调用,以将其发送到后端服务器

API端点往返

以下是部分:前端后端前端开发API端点(例如/ api / user / get)时,您通常会遵循这种模式。首先,我们需要调用Fetch API来触发到端点的HTTP请求。

前端API

这是给我们两个Fetch API请求的简单代码。目前,我们只需执行这两个操作即可构建我们的地理位置API。在本文的稍后部分,我将向您展示它们如何在后端连接到Mongo。

    类用户{
constructor(){
            / *当前未使用* / 
            此 .array = [];
}
}
    //使JSON有效负载
    let make = function(payload){ return {method:'post',
 标头:{'Accept':'application / json',
'Content-Type':'application / json'},
正文:JSON.stringify(payload)};
}
    / * / api / add / user
 将用户的地理位置发送到mongo
 有效载荷= {x:0,y:0,纬度:0.0,lon:0.0} * / 
User.add = 函数(有效载荷){
fetch(“ / api / add / user”,make(有效载荷))
.then(promise => promise.json())。then(json => {
            如果(json.success)
console.log(`已输入位置数据。);
            其他
console.warn(`位置无法输入!`);
});
}
    / * / api / get / users
获取共享它的所有用户的地理位置* /
User.get = function(payload){
fetch(“ / api / get / users,make(payload))
.then(承诺=> promise.json())
.then(json => {
            如果(json.success)
console.log(`位置数据已成功获取。);
其他
console.warn(`无法获取用户!);
});
}

现在,我们可以使用静态用户函数来进行Fetch API调用。当然,没有什么阻止您简单地在代码中任何有意义的地方调用fetch函数。只是将所有内容放入User对象可帮助我们组织代码。

后端

本教程假定您正在运行Node and Express。显示如何进行设置将需要另外一个完整的教程。但是,这是Express中编码的核心API命令。这很简单。

下面的代码来自express.js文件-完整的SSL服务器。如果计划在远程主机上实施此更改,则唯一需要更改的就是使用certbot和LetsEncrypt生成自己的SSL证书。

Express,Multer和Mongo Init Shenanigans

首先,我们需要初始化所有内容:

/ *包括普通服务器软件包... * / const express = require('express');const https = require('https');const fs = require('fs');const path = require('path');/ * multer是用于上传图片的模块* / const multer = require('multer');/ * sharp与multer一起调整图像大小* / const sharp = require('sharp');/ *实例化express应用... * / const app = express();const端口= 443;//创建Mongo客户端const MongoClient = require('mongodb')。MongoClient;// Multer中间件设置const storage = multer.diskStorage({
目的地:功能(要求,文件,cb){cb(null,'。/ sunsets')},
文件名:函数(要求,文件,cb){cb(null,file.fieldname +'-'+ Date.now())}});// Multer将自动创建文件夹上传(” ./sunsets')const的上传= multer({存储:存储});// body-parser是快速安装中随附的中间件。发送POST正文需要以下3行;如果不包括它们,则POST正文将为空。const bodyParser = require('body-parser');app.use(bodyParser.urlencoded({extended:true}));app.use(bodyParser.json());//创建一些静态目录。您网站上的静态文件夹实际上并不存在。它只是另一个文件夹的别名。但是您也可以将其映射为相同的名称。在这里,我们只是向前端公开一些文件夹。app.use('/ static',express.static('images'));app.use('/ sunsets',express.static('sunsets'));app.use('/ api',express.static('api'));app.use('/ static',express.static('css'));app.get('/',function(req,res){res.sendFile(path.join(__ dirname +'/index.html'));});//通用的响应函数-将json对象发送回浏览器以响应请求函数 response(response,content){ const jsontype =“ {'Content-Type':'application / json'}”;
response.writeHead(200,jsontype);
response.end(content,'utf-8');}//实用程序函数...将缓冲区转换为JSON对象函数 json(chunks){ return JSON.parse(Buffer.concat(chunks).toString())}

我们仍然需要将端点添加到express.js文件。假定下面的代码位于我们上面编写的文件下面的同一文件中。

设置API端点

使用Express创建POST API端点很容易。当我们使用前面提到的从客户端(使用User对象及其静态方法)进行的访存调用时,以下代码将在服务器上触发

API端点1 / api / add / user

该服务器端端点会将地理位置数据添加到Mongo数据库。

//端点:api / add / user// POST方法路线-将地理位置添加到Mongo的摄影师集合 app.post('/ api / add / user',函数(req,res,next){ const ip = req.connection.remoteAddress; const {x,y,lat ,lon} = req.body;
  
  //连接到mongo,如果尚不存在此用户,则插入该用户
  MongoClient .connect(`mongodb:// localhost /`,function(err,db){ const Photographer = db.collection('Photographer');
    
    //检查此用户是否已经存在于
    摄影师组 .count({ip:ip})。then(count => {
如果(count == 1){
console.log(`$ {ip}的用户已经在mongo中了。);
db.close();
} 其他 {
console.log(`$ {ip}的用户在mongo中不存在...插入...`);
            让用户= {ip:ip,x:x,y:y,lat:lat,lon:lon};
            
            //插入地理位置数据!
Photographer.insertOne(用户,(错误,结果)=> {
如果(错误)
                    扔埃罗;
                    
                // console.log(“ insertedCount =”,result.insertedCount);
// console.log(“ ops =”,result.ops);
db.close();
});
}
});
res.end('ok');
});});

API端点2 / api / get / users

该服务器端端点将以JSON格式获取Mongo数据库中所有当前存储的地理位置的列表。

//端点:api / get / users// POST方法路线-从Mongo的摄影师集合 app.post('/ api / get / users',函数(req,res,next)中获取所有地理位置 {
  //连接到Mongo服务器
  MongoClient .connect(`mongodb:// localhost /`,函数(err,db){ const Photographer = db.collection('Photographer');
Photographer.find({},{},function(err,cursor){
    
      //注意:您必须将limit()应用于光标
//,然后从数据库中检索任何文档。
cursor.limit(1000);
      让用户= [];
      
      // console.log(cursor); 
cursor.each(function(error,result){ if(error)throw error; if(result){
 // console.log(result); 
            让用户= {x:result.x,y:result.y,lat: result.lat,lon:result.lon};
// console.log(“ user [” + users.length +“] =”,用户);
users.push(用户);
}
});
        //更合适的实现:(WIP) 
(异步函数(){ 
 const cursor = db.collection(“ Photographer”)。find({}); while(await cursor.hasNext()){ const doc = 等待光标。 next(); //在此处处理文档
}
})();
        setTimeout(time => { const json =`{“ success”:true,“ count”:$ {users.length},“ userList”:$ {JSON.stringify(users}}}``; 响应(res,json) ;
},2000);
}); 
});});

API端点3

这将通过Node multer从HTML表单上传图像

//端点:api / sunset / upload// POST方法路由-使用multer app.post('/ api / sunset / upload',upload.single('file'),function(req,res,next)从表单中上传图片 { if(req.file) { // console.log(“ req.file.mimetype”,req.file.mimetype);
// const {filename:image} = req.file.filename; 
      让 ext = req.file.mimetype.split('/')[1];让 Stamp = new Date()。getTime();// console.log(“ ext =”,ext);
输出=`./sunsets/sunset-$ {stamp}。$ {ext}`;
output2 =`https://www.infinitesunset.app/sunsets/sunset-$ {stamp}。$ {ext}`;
console.log(“ output =”,output);
      // console.log(“ output2 =”,output2);
锋利的(req.file.path)
.resize(200).toFile(output,(err,info)=> {
            // console.log(err);
// console.log(info.format); 
});
      // fs.unlinkSync(req.file.path);
res.end(`<html> <body style ='font-size:50px'> <img src =“ $ {output2}” style =“ width:100%;”> <div style =“ text-align:center ; margin-top:50px;“>已上传图片!<a href ='https://www.infinitesunset.app' target ='sunset'>返回</a> </ div> </ body> </ html >`,`utf-8`);
}
    // req.file是`avatar`文件
// req.body将保存文本字段(如果有的话)
res.end(`<html> <body>出问题了。</ body> </ html>`,`utf-8`);});

MongoDB命令概述

首先,我们将使用.insertOne.find Mongo收集方法。插入位置条目时,我们将测试该条目是否已存在于数据库中。如果是这样,则无事可做。如果没有,我们将插入一个新条目。

您还可以使用Mongo的.count方法对与特定文档过滤器匹配的文档中的条目数进行计数。

要执行任何Mongo操作,我们首先需要从Node应用程序内部连接到Mongo服务器!这是使用.connect方法完成的

。连接

MongoClient .connect(mongodb:// localhost /,函数(err,db){ / * mongo code * / };

db.close()

完成后,我们需要关闭数据库连接:

MongoClient .connect(mongodb:// localhost /,函数(err,db){
db.close();};

.insertOne

Photographer.insertOne(user,(erro,result)=> { if(error) throw error;
        
    // console.log(“ insertedCount =”,result.insertedCount);
// console.log(“ ops =”,result.ops);
    
    别忘了关闭数据库
db.close();});

在这里,results.ops将显示插入的对象。

。找

find方法在Mongo中产生称为游标的东西该光标是一个对象,您可以调用.each来遍历所有找到的项目。根据Mongo文档,您应该始终首先使用cursor.limit(1000);设置一个限制

Photographer.find({},{},function(err,cursor){
      //注意:您必须将limit()应用于光标
//,然后从数据库中检索任何文档。
cursor.limit(1000);
      
让用户= [];
      
      // console.log(cursor)是[Cursor object]; 
cursor.each(函数(错误,结果){
      
          //检查错误
          ,如果(错误) 抛出的错误;
              
          //获取数据
          let x = result.x;令 y = result.y;
          
          / *等... * /
}}

前端

显示数据。

现在,我们已经在后端运行了基本的Mongo API,我们可以将数据发送回前端,并且客户端需要在屏幕上直观地显示数据。

我选择使用HTML5 <canvas>将坐标绘制为图像。要在画布上绘制图像,首先必须将它们作为带有IMG标签的常规图像包含在HTML文档中。要准备图像,让我们包括将其缓存在浏览器中:

<style type =“ text / css”> / *加载图像但将其移出屏幕* /#you,#world,#mark {位置:绝对;顶部:-1000px;左:-1000px} </ style><img src =“ you.png” id =“ you” /> <-您的位置-> <img src =“ world.png” id =“ world” /> <-世界地图图像-> < img src =“ marker.png” id =“ marker” /> <-通用位置标记->

现在是我们前端的核心。此调用将执行很多操作:查看设备浏览器是否支持HTML5地理位置属性,创建2D画布在其上绘制世界地图图像,获取HTML5地理位置数据,使用Fetch API将其发送到Mongo,再进行一次调用以获取之前的所有信息通过基于返回的JSON对象绘制标记,将项目插入后端的mongo数据库中并为画布设置动画:

<script type =“ module”>
    //创建有效负载-到处都是冗余的
//因为所有POST负载都是JSON
//现在在整洁的make()函数中
    let make = function(payload){ return {method:'post',
标头:{'Accept':'application / json'},
 正文:JSON.stringify(payload)};
});
    //安全的入口点,已加载所有图像,等等 
。window.onload = 函数(事件){
        //一个存储位置标记的地方
window.markers = [];
        //因为这是<script type =“ module”,所以要创建User对象
//全局可用,因此可以在HTML属性事件中使用,
//我们必须手动将其添加到window对象
window.onload = U => {
window.User =用户;
}
        //创建2D canvas 
        const c = document.getElementById(“ canvas”);const ctx = c.getContext(“ 2d”);
        //获取图像
        const world = document.getElementById(“ world”);const here = document.getElementById(“ here”);const marker = document.getElementById(“ marker”);
        如果(navigator.geolocation){
navigator.geolocation.getCurrentPosition(函数(位置){
                让 lat = position.coords.latitude;令 lon = position.coords.longitude;令 xy = World2Image(lat,lon);令 x = xy [0];令 y = xy [1];
console.log(`您处于$ {lat} x $ {lon}或= $ {x} x $ {y}`);
                //将此用户添加到mongo
User.add({x:x,y:y,lat:lat,lon:lon});
                //获取我们的用户位置
fetch(“ / api / get / users”,make({}))。then(
promise => promise.json())。then(json => {
                    / *存储返回的标记列表* /
window.markers = json.userList;
                    //选择性地调试每个条目:
json.userList.forEach(摄影师=> {
                         // console.log(photographer);
});
                    //删除加载栏
window [“ loading”]。style.display ='none';
                    //显示返回的项目数
console.log(“ json.userList.length”,json.userList.length);
});
                //实时绘制所有位置的动画循环
                function loop(){ if(here && ctx){ //绘制世界地图
ctx.drawImage(world,0,0,920,468);
ctx.save();
                        //移动到画布的中心
ctx.translate(x,y);
                        //绘制图像
ctx.drawImage(此处-here.width / 2,-here.width / 2);
                        //绘制标记图像
ctx.translate(-x,-y);
如果(window.cameras){
window.cameras.forEach(cam =>
ctx.drawImage(宝丽来,
cam.x-polaroid.width / 2,
cam.y-polaroid.width / 2));
}
ctx.restore(); //恢复上下文
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
});
} else msg.innerHTML =“此浏览器不支持地理位置。
}</ script>

注意...您不必以这种确切方式呈现数据。如果您使用的是React库,请继续使用组件。没关系 在这里,我仅将Vanilla JavaScript用于此示例。重要的是获取请求以及我们正在屏幕上呈现包含位置数据的返回的JSON对象。您不必使用画布。您可能只为每个标记使用了DIV元素。

nfinitesunset.app实时摄影应用程序中打开本教程演示

我在GitHub上将整个项目开源

检查此Express.js SSL MongoDB服务器的完整源代码对于那些试图让Mongo在远程主机上工作的人来说,这是一个很好的起点。⭐加星标,Star 
2023-03-22 10:04:19

新人小程序+APP定制199元起


发放福利,助力中小企业发展,真正在互联网中受益

点击询问定制

广告服务展示