javascript - 如何将 API 数据动态传递给 MongoDB 数据库
问题描述
我正在使用AISHub API 构建一个小船可视化器。查询 API 后,我可以获取包含容器的 json 文件,并仅使用我感兴趣的容器进行过滤,并将它们注入网页上的表格中。API 提供以下文件:
[NAME, MMSI, LONGITUDE, LATITUDE]
. 我可以正确连接到MongoDB
我npm start
。
问题:我还想MongoDB
每 5 分钟将这些数据发送到数据库中的集合。我尝试了许多不同的方法来做到这一点,但它们似乎都没有奏效。
很难考虑代码的哪些部分通过,哪些不通过,但我相信下面有足够的信息来理解问题所在:
app.js是我设置MongoDB
连接的地方
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var mongoose = require('mongoose');
const bodyParser = require('body-parser');
const vesselController = require('./controllers/VesselController');
require('./config/keys');
var app = express();
app.use(cors());
app.options('*', cors());
// DB Config
const db = require('./config/keys').MongoURI;
const options = {
useNewUrlParser: true,
reconnectTries: Number.MAX_VALUE,
poolSize: 10
};
mongoose
.connect(db, options)
.then(() => console.log('MongoDB Connection established'))
.catch((err) => console.log('Error connecting MongoDB database due to: ', err));
const PORT = process.env.PORT || 3000;
app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(cors());
app.route('/vessels/all').get(vesselController.getBaseAll);
app.route('vessels/:id/track').get(vesselController.getCurrent);
app.route('/vessels').get(vesselController.getHistory);
app.listen(PORT, console.log(`Server started on port ${PORT}`));
module.exports = app;
index.js是我缓存数据的地方(以及我认为应用程序应该将数据发送到的地方MongoDB
)
var express = require('express');
var router = express.Router();
var axios = require('axios');
const NodeCache = require('node-cache');
const myCache = new NodeCache();
let hitCount = 0;
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
const mmsiOfInterest = [
'367029520',
'366909730',
'367128570'
];
const shipNamesOfInterest = [
'MICHIGAN',
'JP BOISSEAU',
'DELAWARE BAY'
];
router.get('/hello', async function(req, res, next) {
const allData = myCache.get('allData');
if (!allData) {
hitCount++;
console.log(`hit ${hitCount} number of times`);
const { data } = await axios.get(
'http://data.aishub.net/ws.php?username=KEY&format=1&output=json&compress=0&latmin=11.42&latmax=58.20&lonmin=-134.09&lonmax=-52.62'
);
const [ metaData, ships ] = data;
console.log(data);
const shipsOfInterest = ships.filter(
(ship) => mmsiOfInterest.includes(ship.MMSI) || shipNamesOfInterest.includes(ship.NAME)
);
myCache.set('allData', shipsOfInterest, 70);
res.send(data);
return;
}
res.send(allData);
});
module.exports = router;
VesselController.js:我拥有获取不同信息的功能,例如当前船只、所有船只、船只历史
module.exports.getBaseAll = (req, res) => {
Promise.all([
Compnanies.find(),
Vessels.find(),
Positions.aggregate([
{
$sort: {
date: -1
}
},
{
$group: {
_id: '$callsign',
details: {
$push: '$$ROOT'
}
}
},
{
$replaceRoot: {
newRoot: {
$arrayElemAt: [ '$details', 0 ]
}
}
}
])
])
.then(([ companies, vessels, positions ]) => {
// apply vessels detail table as join:
positions.forEach((pos) => {
vessels.forEach((ves) => {
if (pos.callsign == ves.callsign) {
p._detail = ves;
}
});
companies.forEach((com) => {
if (p._detail.company == com.number) {
p._detail = com;
}
});
});
res.status(200).json(positions);
})
.catch((err) => {
return res.status(500).send(err);
});
console.log(vesselController.getBaseAll);
};
module.exports.getHistory = (req, res) => {
var id = req.param.id;
Positions.find(
{
callsign: id,
date: {
$gte: new Date(Date.now() - 1000 * 60 * 60 * 24)
}
},
(err, task) => {
if (err) {
return res.status(500).send(err);
}
res.status(200).json(task);
}
);
console.log(vesselController.getHistory);
};
module.exports.getCurrent = (req, res) => {
var currentPos = Positions.find({
date: {
$gte: new Date(Date.now() - 1000 * 60 * 60)
}
});
currentPos.exec((err, task) => {
if (err) {
return res.status(500).send(err);
}
res.status(200).json(task);
});
console.log(vesselController.getCurrent);
};
在LatitudeLongitude.js我根据MongoDB
文档设置了正确的格式
const mongoose = require('mongoose');
const LatitudeLongitudeSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
mmsi: {
type: Number,
required: false
},
longitude: {
type: Number,
required: false
},
latitude: {
type: Number,
required: false
}
});
const LatitudeLongitude = mongoose.model('LatitudeLongitude', LatitudeLongitudeSchema);
module.exports = LatitudeLongitude;
users.js是我设置router.post
var express = require('express');
var router = express.Router();
const LatitudeLongitude = require('../models/LatitudeLongitude');
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.post('/vessles/map', function(req, res) {
const { name, mmsi, longitude, latitude } = req.body;
let errors = [];
// Check required fields
if (!name || !mmsi || !longitude || !latitude) {
errors.push({ msg: 'No data received' });
}
if (
LatitudeLongitude.findOne({ mmsi: mmsi }).then((pos) => {
if (pos) {
// vessel exists
const newVessel = new Vessles({
name,
mmsi,
longitude,
latitude
});
}
})
);
});
module.exports = router;
在里面的集合集合下面MongoDB
,显然是空的:
我怎样才能成功地将上面提到的 API 中的信息传递到我的MongoDB
?
到目前为止我所拥有的:
我尝试了许多不同的方法来将数据从 API 传递到MongoDB
每 5 分钟一次。在不同的方法中,我认为我在这篇文章中包含的方法是最有效的,但是缺少一些我无法捕捉/理解的东西。
我相信文件index.js应该是负责执行此操作的文件,因为我预先设置了该文件中的所有检查。但是,我现在很困惑这是否是正确的位置。app.route('/vessels/all').get(vesselController.getBaseAll);
您在app.js文件中看到路由的原因是,Postman
一旦一切正常,我将使用它作为端点 api 检查。我想我会把它留在那里,这样你就可以看到我是如何设计这个过程的。
感谢您阐明此事。
解决方案
在我看来,您应该首先通过将以下代码附加到您的 server.js 文件来测试我的方法。然后重构它
setInterval( () => { fetch(' http://your/get/route ').then( updateDB() ).catch(doWhateverYouWant()); },3000 );
推荐阅读
- r - 在创建具有日期可用性的数据框时保留原始 ID 列
- reactjs - HttpOnly cookie 未保存在浏览器中
- ftp - FtpSession.exist(path) 不适用于文件
- docker - docker 无法使用非 root 用户在已安装的卷上写入
- design-patterns - 游戏设计:将渲染与逻辑分离:如何?
- python - 为什么我无法访问 open() 的内容
- c# - 如何在 swagger UI 中使用 Swashbuckle 设置内容类型 application/json 和 application/xml
- c++ - 如果已删除对象,如何从向量中删除对象
- activemq-artemis - 如何在不完全重新启动应用程序的情况下将具有复制 HA 的集群从嵌入式代理返回到工作状态?
- flutter - 如何在 Flutter 中使用 ValueListenableBuilder 中的 ValueNotifier?