gpt4 book ai didi

javascript - 简单的$ avg查询Node.js

转载 作者:可可西里 更新时间:2023-11-01 09:48:40 27 4
gpt4 key购买 nike

这是我必须制作该应用程序的所有代码。因此,我可以从csv文件导入数据/记录,也可以从localhost:3000的应用程序手动插入数据,并将其插入数据库中。从那里,我将能够从这里查询。错误位于底部的server.js中。批量和平均似乎都没有执行。

server.js,其中包含批量(用于1000个数据及更多数据)和平均查询(air_temperature)

var express = require('express');
var app = express();
var mongojs = require('mongojs');
var db = mongojs('meibanlist', ['meibanlist']);
var bodyParser = require('body-parser');

app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());

app.get('/meibanlist', function (req, res) {
console.log('I received a GET request');

db.meibanlist.find(function (err, docs) {
console.log(docs);
res.json(docs);
});
});

app.post('/meibanlist', function (req, res) {
console.log(req.body);
db.meibanlist.insert(req.body, function(err, doc) {
res.json(doc);
});
});

app.delete('/meibanlist/:id', function (req, res) {
var id = req.params.id;
console.log(id);
db.meibanlist.remove({_id: mongojs.ObjectId(id)}, function (err, doc) {
res.json(doc);
});
});

app.get('/meibanlist/:id', function (req, res) {
var id = req.params.id;
console.log(id);
db.meibanlist.findOne({_id: mongojs.ObjectId(id)}, function (err, doc) {
res.json(doc);
});
});

app.put('/meibanlist/:id', function (req, res) {
var id = req.params.id;
console.log(req.body.machine_unit);
db.meibanlist.findAndModify({
query: {_id: mongojs.ObjectId(id)},
update: {$set: {machine_unit: req.body.machine_unit, air_temperature: req.body.air_temperature, water_temperature: req.body.water_temperature, heat_temperature: req.body.heat_temperature, room_temperature: req.body.room_temperature, date: req.body.date, time: req.body.time}},
new: true}, function (err, doc) {
res.json(doc);
}
);
});

var cursor = db.meibanlist.find({"air_temperature": { "$exists": true, "$type": 2 }}),
bulkUpdateOps = [];

cursor.forEach(function(doc){
var newTemp = parseInt(doc.air_temperature, 10);
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "air_temperature": newTemp } }
}
});

if (bulkUpdateOps.length === 500) {
db.meibanlist.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});

if (bulkUpdateOps.length > 0) { db.meibanlist.bulkWrite(bulkUpdateOps); }

db.meibanlist.aggregate([
{
"$group": {
"_id": null,
"averageAirTemperature": { "$avg": "$air_temperature" }
}
}
], function(err, results){
if (err || !results) console.log ("record not found");
else console.log(results[0]["averageAirTemperature"]);
});

app.listen(3000);
console.log("Server running on port 3000");

index.html
<!DOCTYPE>
<html ng-app="myApp">
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">

<title>Meiban App</title>
</head>
<body>
<div class="container" ng-controller="AppCtrl">
<h1>Meiban App</h1>

<table class="table">
<thead>
<tr>
<th>Machine unit</th>
<th>Air Temperature</th>
<th>Water Temperature</th>
<th>Heat Temperature</th>
<th>Room Temperature</th>
<th>Date</th>
<th>Time</th>
<th>Action</th>

<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<tr>
<td><input class="form-control" ng-model="contact.machine_unit"></td>
<td><input class="form-control" ng-model="contact.air_temperature"></td>
<td><input class="form-control" ng-model="contact.water_temperature"></td>
<td><input class="form-control" ng-model="contact.heat_temperature"></td>
<td><input class="form-control" ng-model="contact.room_temperature"></td>
<td><input class="form-control" ng-model="contact.date"></td>
<td><input class="form-control" ng-model="contact.time"></td>
<td><button class="btn btn-primary" ng-click="addCollection()">Add Collection</button></td>
<td><button class="btn btn-info" ng-click="update()">Update</button>&nbsp;&nbsp;<button class="btn btn-info" ng-click="deselect()">Clear</button></td>
</tr>
<tr ng-repeat="contact in collection">
<td>{{contact.machine_unit}}</td>
<td>{{contact.air_temperature}}</td>
<td>{{contact.water_temperature}}</td>
<td>{{contact.heat_temperature}}</td>
<td>{{contact.room_temperature}}</td>
<td>{{contact.date}}</td>
<td>{{contact.time}}</td>
<td><button class="btn btn-danger" ng-click="remove(contact._id)">Remove</button></td>
<td><button class="btn btn-warning" ng-click="edit(contact._id)">Edit</button></td>
</tr>
</tbody>
</table>

</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<script src="controller/controller.js"></script>
</body>
</html>

controller.js
var myApp = angular.module('myApp', []);
myApp.controller('AppCtrl', ['$scope', '$http', function($scope, $http) {
console.log("Hello World from controller");


var refresh = function() {
$http.get('/meibanlist').success(function(response) {
console.log("I got the data I requested");
$scope.meibanlist = response;
$scope.contact = "";
});
};

refresh();

$scope.addCollection = function() {
console.log($scope.contact);
$http.post('/meibanlist', $scope.contact).success(function(response) {
console.log(response);
refresh();
});
};

$scope.remove = function(id) {
console.log(id);
$http.delete('/meibanlist/' + id).success(function(response) {
refresh();
});
};

$scope.edit = function(id) {
console.log(id);
$http.get('/meibanlist/' + id).success(function(response) {
$scope.contact = response;
});
};

$scope.update = function() {
console.log($scope.contact._id);
$http.put('/meibanlist/' + $scope.contact._id, $scope.contact).success(function(response) {
refresh();
})
};

$scope.deselect = function() {
$scope.contact = "";
}

}]);

最佳答案

正如文档所指出的那样, $avg 运算符分两个管道步骤工作,即 $project $group 阶段。相信您需要在 $avg 管道中使用 $group 累加器,因为您需要所有价格的平均值。

$group 阶段中使用时, $avg 返回所有数值的总平均值,这些数值是通过将指定的表达式应用于一组由_id字段指出的键共享相同组的文档中的每个文档而得到的。
_id字段是必填字段;但是,由于您要整体计算所有输入文档的累积平均值,因此可以将_id的值指定为null:

db.database.aggregate([
{
"$group": {
"_id": null,
"Average": { "$avg": "$price" }
}
}
], function(err, results){
if (err !results) console.log ("record not found");
else console.log(results[0]["Average"]);
});

整理评论中的信息以及对问题的后续更新后,您遇到了麻烦,因为您的值不是数字,因此 $avg 无法正常工作的原因。

您需要使用 update() 方法将字符串值转换为数字值。此处的概念是 loop through your collection with a cursor,对于光标内的每个文档,请使用 $set 以及 的新值 parseInt() 来更新文档。

假设您的集合不是那么笨拙,则可以使用游标的 forEach() 方法来迭代它并更新集合中符合特定条件的每个文档,从而实现上述直觉。

以下mongo shell演示针对小型数据集重点介绍了这种方法:

mongo shell
db.meibanlist.find({"air_temperature": { "$exists": true, "$type": 2 }})
.snapshot()
.forEach(function(doc){
var newTemp = parseInt(doc.air_temperature, 10);
db.meibanlist.updateOne(
{ "_id": doc._id },
{ "$set": { "air_temperature": newTemp } }
);
});

现在要提高性能,尤其是在处理大型集合时,请利用 Bulk() API批量更新集合。

与上述操作相比,这非常有效,因为使用批量API,您可以将操作分批发送到服务器(例如,批量大小为500),这将使您更好
性能,因为您不会将每个请求发送到服务器,而只是每500个请求发送一次,从而使更新更高效,更快捷。

以下示例演示了如何使用MongoDB版本 Bulk()>= 2.6中提供的 < 3.2 API。

mongo shell
var bulkUpdateOps = db.meibanlist.initializeUnOrderedBulkOp(),   
counter = 0;

db.meibanlist.find({"air_temperature": { "$exists": true, "$type": 2 }})
.snapshot()
.forEach(function(doc){
var newTemp = parseInt(doc.air_temperature, 10);
bulkUpdateOps.find({ "_id": doc._id })
.update({ "$set": { "air_temperature": newTemp } })

counter++; // increment counter for batch limit
if (counter % 500 === 0) {
// execute the bulk update operation in batches of 1000
bulkUpdateOps.execute();
// Re-initialize the bulk update operations object
bulkUpdateOps = db.meibanlist.initializeUnOrderedBulkOp();
}
})

// Clean up remaining operation in the queue
if (counter % 500 !== 0) { bulkUpdateOps.execute(); }

下一个示例适用于MongoDB 3.2版及更高版本,该版本自 deprecated以来一直具有 Bulk() API,并使用 bulkWrite() 提供了一组较新的api。

它使用与上述相同的游标,但使用相同的 forEach() 游标方法通过批量操作创建数组,以将每个批量写入文档推入数组。由于写命令最多只能接受1000个操作,
您将需要对操作进行分组以最多包含1000个操作,并在循环达到1000次迭代时重新初始化数组。如果集合很大,则上面的counter变量可以有效地管理批量更新。它允许您分批更新操作,并以500为批次将写操作发送到服务器,这使您具有更好的性能,因为您没有将每个请求发送到服务器,而是每500个请求发送一次。

对于批量操作,MongoDB会对每个批次施加默认的内部限制,即1000个操作,因此从可以控制批量大小的 Angular 而不是让MongoDB施加默认值的意义上来说,最好选择500个文档,即,对于规模较大的操作超过1000个文档。
var cursor = db.meibanlist.find({"air_temperature": { "$exists": true, "$type": 2 }}),
bulkUpdateOps = [];

cursor.forEach(function(doc){
var newTemp = parseInt(doc.air_temperature, 10);
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "air_temperature": newTemp } }
}
});

if (bulkUpdateOps.length === 500) {
db.meibanlist.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});

if (bulkUpdateOps.length > 0) { db.meibanlist.bulkWrite(bulkUpdateOps); }

更新集合后,您就可以在 $avg函数中愉快地应用 aggregate() 运算符。以下将返回所有合并文档的平均 air_temperature:
db.meibanlist.aggregate([
{
"$group": {
"_id": null,
"averageAirTemperature": { "$avg": "$air_temperature" }
}
}
], function(err, results){
if (err !results) console.log ("record not found");
else console.log(results[0]["averageAirTemperature"]);
});

更新

上面的代码在mongo shell中有效。对于mongojs版本,将操作封装在需要时可以调用的函数中。例如,您可以将批量更新逻辑放在其自己的函数bulkUpdate中:
function bulkUpdate(collection, callback)
var ops = [];

collection.find({
"air_temperature": { "$exists": true, "$type": 2 }
}, function (err, docs) {
docs.forEach(function(doc){
ops.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": {
"air_temperature": parseInt(doc.air_temperature, 10),
"water_temperature": parseInt(doc.water_temperature, 10),
"heat_temperature": parseInt(doc.heat_temperature, 10),
"room_temperature": parseInt(doc.room_temperature, 10)
}
}
}
});

if (ops.length === 500) {
collection.bulkWrite(bulkUpdateOps, function(err, result){
if (err) callback(err);
callback(null, result);
});
ops = [];
}
});

if (ops.length > 0) {
collection.bulkWrite(ops, function(err, result){
callback(null, result);
});
}
});
}

以及获得平均温度的逻辑:
function getAverageTemps(collection, callback) {
collection.aggregate([
{
"$group": {
"_id": null,
"averageAirTemperature": { "$avg": "$air_temperature" },
"averageWaterTemperature": { "$avg": "$water_temperature" },
"averageHeatTemperature": { "$avg": "$heat_temperature" },
"averageRoomTemperature": { "$avg": "$room_temperature" }
}
}
], function(err, results){
if (err || !results) callback(err);
else callback(null, results);
});
}

然后可以按以下方式调用它,例如,可以在API中放置一个用于检索平均温度的终结点:
app.get('/meibanlist/averagetemps', function (req, res) {
getAverageTemps(db.meibanlist, function (err, temps) {
if (err || !temps) console.log ("record not found");
else res.json(temps);
});
});

关于javascript - 简单的$ avg查询Node.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41436078/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com