gpt4 book ai didi

node.js - 如何在 Mongoose Model.bulkWrite 操作期间获取字段值?

转载 作者:太空宇宙 更新时间:2023-11-04 01:20:46 25 4
gpt4 key购买 nike

上下文:

我正在尝试批量插入数据数组,并附加一个计算字段:“状态”。
状态应该是:
- “New”表示新插入的文档;
- 对于数据库中存在但传入数据集中不存在的文档,“已删除”;
- 解释字段价格演变的百分比,将数据库中的值与传入数据集中的值进行比较。

实现:

data.model.ts

import { Document, model, Model, models, Schema } from 'mongoose';
import { IPertinentData } from './site.model';

const dataSchema: Schema = new Schema({
sourceId: { type: String, required: true },
name: { type: String, required: true },
price: { type: Number, required: true },
reference: { type: String, required: true },
lastModified: { type: Date, required: true },
status: { type: Schema.Types.Mixed, required: true }
});

export interface IData extends IPertinentData, Document {}

export const Data: Model<IData> = models.Data || model<IData>('Data', dataSchema);

data.service.ts

import { Data, IPertinentData } from '../models';

export class DataService {
static async test() {
// await Data.deleteMany({});

const data = [
{
sourceId: 'Y',
reference: `y0`,
name: 'y0',
price: 30
},
{
sourceId: 'Y',
reference: 'y1',
name: 'y1',
price: 30
}
];

return Data.bulkWrite(
data.map(function(d) {
let status = '';
// @ts-ignore
console.log('price', this);

// @ts-ignore
if (!this.price) status = 'New';
// @ts-ignore
else if (this.price !== d.price) {
// @ts-ignore
status = (d.price - this.price) / this.price;
}

return {
updateOne: {
filter: { sourceId: d.sourceId, reference: d.reference },
update: {
$set: {
// Set percentage value when current price is greater/lower than new price
// Set status to nothing when new and current prices match
status,
name: d.name,
price: d.price
},
$currentDate: {
lastModified: true
}
},
upsert: true
}
};
}
)
);
}
}

...然后在我的后端 Controller 中,我只是用一些路由来调用它:

try {
const results = await DataService.test();
return new HttpResponseOK(results);
} catch (error) {
return new HttpResponseInternalServerError(error);
}

问题:

我尝试了很多实现语法,但都失败了,因为类型转换、不受支持的语法(如 $ 符号)以及聚合造成的限制...

我觉得上述解决方案可能最接近工作场景,但我缺少一种在实际计算状态之前获取价格字段值并用更新值替换的方法。
这里 this 的值未定义,但它应该指向当前文档。

问题:

  1. 我是否使用正确的Mongoose 方式进行批量更新?
  2. 如果是,如何获取字段值?

环境:

NodeJS 13.x
Mongoose 5.8.1
MongoDB 4.2.1

最佳答案

发现了!

终于找到了一个有效的语法,pfeeeew...

...
return Data.bulkWrite(
data.map(d => ({
updateOne: {
filter: { sourceId: d.sourceId, reference: d.reference },
update: [
{
$set: {
lastModified: Date.now(),
name: d.name,
status: {
$switch: {
branches: [
// Set status to 'New' for newly inserted docs
{
case: { $eq: [{ $type: '$price' }, 'missing'] },
then: 'New'
},
// Set percentage value when current price is greater/lower than new price
{
case: { $ne: ['$price', d.price] },
then: {
$divide: [{ $subtract: [d.price, '$price'] }, '$price']
}
}
],
// Set status to nothing when new and current prices match
default: ''
}
}
}
},
{
$set: { price: d.price }
}
],
upsert: true
}
}))
);
...

说明:

有几个问题阻碍了我:

  1. 使用“$field_value_to_check”代替带有未定义“this”的 this.field ...
  2. 带有 $ 符号的语法似乎仅在聚合更新中起作用,使用 update: [] 即使内部只有一个 $set ...
  3. 在 upsert 过程中用于插入文档的第一个条件需要检查字段 price 是否存在。只有 BSON $type 的语法有效...

希望它可以帮助处于相同场景的其他开发者。

关于node.js - 如何在 Mongoose Model.bulkWrite 操作期间获取字段值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59374431/

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