我正在使用MongoDB和mongoose。我有一个订单集合,每个订单都有currenc(usd,eur,ils等)和百分比。
我的节点应用程序从另一个服务读取一个值,我的Order集合中有一个名为price的虚拟字段,该字段是根据该值和订单文档的百分比计算的。
import mongoose, { Schema } from 'mongoose';
import { priceValue } from '../services/price-value';
const orderSchema = new Schema({
currency: {
type: 'String',
required: true
},
percent: {
type: 'Number',
required: true
}
}, {
toObject: {
virtuals: true
},
toJSON: {
virtuals: true
}
});
orderSchema.virtual('price').get(function() {
return priceValue * this.percent;
});
export default mongoose.model('Order', orderSchema);
我需要找到每种货币的最高价格。对于每个CURRENCY调用,类似于:
db.orders.find({ currency: CURRENCY }).sort({percent: -1}).limit(1);
在节点应用程序中收集结果并计算虚拟价格字段 但这感觉不对。这样做的正确方法是什么?
答案 0 :(得分:0)
根据this answer,您需要汇总,它只需一次调用数据库
db.orders.aggregate([
{ "$sort": { "currency": 1, "percent": -1 } }, // or "percent": 1
{ "$group": {
"_id": "$currency",
"percent": { "$first": "$percent" }
}}
])
结果应该类似于,按最大百分比排序,并按货币
进行唯一分组[{_id: 'usd', percent: 12}, {_id: 'eur', percent: 34}]
然后你可以使用你的
import { priceValue } from '../services/price-value';
获得价格
答案 1 :(得分:0)
不是使用“虚拟字段”,而是将其委托给聚合框架,这比查询每个可能的“货币”值要好得多。
priceValue
是一个简单的“常量”值,那么你只需将它提供给管道表达式:
db.orders.aggregate([
{ "$sort": { "currency": 1, "percent": -1 } },
{ "$group": {
"_id": "$currency",
"percent": {
"$first": {
"$multiply": [
{ "$divide": [ "$percent", 100 ] },
priceValue
]
}
}
}}
])
所以你$sort
要按照“货币”的顺序保存事物,然后按照“货币”的每个“百分比”降序。然后根据每个不同的“货币”$group
,从每个分组边界取$first
。
然后您需要做的就是priceValue
常量从$multiply
之后的100
<section id="intro">...</section>
<div id="content">...</div>
<aside id="nav">...</aside>
<footer>...</footer>
开始,将$divide
应用于返回值,因为您需要实际存储的整个值的除数。
您还应该知道,聚合管道中返回的文档与使用的模型没有相同的架构附加方法。基本原因是您通常会“更改所返回文档的形状”,因此“架构”不再适用。