获取每种记录类型的最大虚拟字段

时间:2017-10-23 20:59:43

标签: node.js mongodb mongoose aggregation-framework

我正在使用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);

在节点应用程序中收集结果并计算虚拟价格字段 但这感觉不对。这样做的正确方法是什么?

2 个答案:

答案 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应用于返回值,因为您需要实际存储的整个值的除数。

您还应该知道,聚合管道中返回的文档与使用的模型没有相同的架构附加方法。基本原因是您通常会“更改所返回文档的形状”,因此“架构”不再适用。