mongodb - 根据对象中的值使用不同的步骤
问题描述
使用 Mongoose,我创建了三个模型,一个称为movements
,两个子模型称为inMovement
and outMovement
。
const movementSchema = new Schema({
actualState: {
type: Schema.Types.ObjectID,
ref: 'statemovements'
},
movementDate: {
type: Date,
required: true
},
business: {
type: Schema.Types.ObjectID,
ref: 'business',
required: true
},
inspectors: [{
type: String
}],
transport: {
type: Schema.Types.ObjectID,
ref: 'transports'
},
estimatedTime: Number,
employees: Number,
manHours: Number,
filesLocations: [{ type: String }],
dock: Boolean,
door: Number
},{
timestamps: true,
discriminatorKey: '__type'
});
const inMovementSchema = new Schema({
productsList: [{
product: {
type: Schema.Types.ObjectID,
ref: 'products'
},
packages: Number,
weight: Number,
disposition: Boolean
}]
});
const outMovementSchema = new Schema({
productsList: [{
product: {
type: Schema.Types.ObjectID,
ref: 'products'
},
exporter: {
type: Schema.Types.ObjectID,
ref: 'business'
},
importer: {
type: Schema.Types.ObjectID,
ref: 'business'
},
packages: Number,
weight: Number,
disposition: Boolean,
labeled: {
type: Schema.Types.ObjectID,
ref: 'labels'
}
}],
booking: String,
thermograph: {
type: Schema.Types.ObjectID,
ref: 'thermographs'
},
photographic: Boolean,
hasStock: Boolean,
isExport: Boolean,
internalDestination: {
type: Schema.Types.ObjectID,
ref: 'establishments'
},
externalDestination: {
type: Schema.Types.ObjectID,
ref: 'countries'
}
});
最终结果是一个movements
包含文档的集合,其中包含一个名为的值,该值__type
可以是inMovements
或outMovements
。在此之后,我为每个模型制作了三个不同的控制器,一个只请求inMovements
,另一个只请求outMovements
,最后一个movements
用于两种类型的文档(除了模型之外,它们在三个中是相同的)。
movementsCTRL.getMixedMovements = async (req, res) => {
let skip = 0;
let limit = 10;
let sort = { _id: 'asc' };
let search = {};
if (req.params.first != undefined && req.params.rows != undefined) {
skip = filterFunc.calculateSkip(req.params.first);
limit = filterFunc.calculateLimit(req.params.rows);
}
if (req.params.search != undefined) {
search = filterFunc.calculateSearch(req.params.search);
}
if (req.params.sort != undefined) {
sort = filterFunc.calculateSort(req.params.sort);
}
movementsModel
.aggregate(pipelines.movementAggregate)
.match(search)
.sort(sort)
.skip(skip)
.limit(limit)
.exec((err, ret) => {
if (err) {
res.status(500).json({ message: err.message });
}
else {
movementsModel.countDocuments(search, (err, count) => {
if (err) {
res.status(500).json({ message: err.message });
}
else {
res.json({ count: count, values: ret });
}
});
};
});
}
现在,我需要为每个模型制作管道,inMovements
并为outMovements
. 管道的数组保存在另一个类中,因此我可以在任何地方调用我需要的管道。
pipelines.inmovementAggregate = [
{
"$lookup": {
from: 'transports',
localField: 'transport',
foreignField: '_id',
as: 'transport'
}
}, {
"$unwind": {
"path": '$transport',
"preserveNullAndEmptyArrays":true
}
}, {
"$addFields": {
"products_id": {
"$reduce": {
"input": "$productsList",
"initialValue": [],
"in": "$$this.product"
}
}
}
}, {
"$lookup": {
from: 'products',
localField: 'products_id',
foreignField: '_id',
as: 'products_id'
}
}, {
"$addFields": {
"productsList": {
"$map": {
"input": "$productsList",
"as": "productList",
"in": {
"$mergeObjects": [
"$$productList",
{
"product": {
"$arrayElemAt": [
"$products_id",
{ "$indexOfArray": ["$products_id", "$$productList.product"] }
]
}
}
]
}
}
}
}
}, {
"$project": { "products_id": 0 }
}, {
"$lookup": {
from: 'businesses',
localField: 'business',
foreignField: '_id',
as: 'business'
}
}, {
"$unwind": {
"path":'$business',
"preserveNullAndEmptyArrays":true
}
},{
"$lookup": {
from: 'countries',
localField: 'business.country',
foreignField: '_id',
as: 'business.country'
}
}, {
"$unwind": {
"path": '$business.country',
"preserveNullAndEmptyArrays":true
}
}, {
"$lookup": {
from: 'statemovements',
localField: 'actualState',
foreignField: '_id',
as: 'actualState'
}
}, {
"$unwind": {
"path": '$actualState',
"preserveNullAndEmptyArrays":true
}
}
]
pipelines.outmovementAggregate = [
{
"$lookup": {
from: 'transports',
localField: 'transport',
foreignField: '_id',
as: 'transport'
}
}, {
"$unwind": {
"path":'$transport',
"preserveNullAndEmptyArrays":true
}
}, {
"$addFields": {
"products_id": {
"$reduce": {
"input": "$productsList",
"initialValue": [],
"in": "$$this.product"
}
}
}
}, {
"$lookup": {
from: 'products',
localField: 'products_id',
foreignField: '_id',
as: 'products_id'
}
}, {
"$addFields": {
"exporters_id": {
"$reduce": {
"input": "$productsList",
"initialValue": [],
"in": "$$this.exporter"
}
}
}
}, {
"$lookup": {
from: 'businesses',
localField: 'exporters_id',
foreignField: '_id',
as: 'exporters_id'
}
}, {
"$addFields": {
"countries_id": {
"$reduce": {
"input": "$exporters_id",
"initialValue": [],
"in": "$$this.country"
}
}
}
}, {
"$lookup": {
from: 'countries',
localField: 'countries_id',
foreignField: '_id',
as: 'countries_id'
}
}, {
"$addFields": {
"exporters_id": {
"$map": {
"input": '$exporters_id',
"as": "businessE",
"in": {
"$mergeObjects": [
"$$businessE",
{
"country": {
"$arrayElemAt": [
"$countries_id",
{ "$indexOfArray": ["$countries_id", "$$businessE.country"] }
]
}
}
]
}
}
}
}
}, {
"$addFields": {
"importers_id": {
"$reduce": {
"input": "$productsList",
"initialValue": [],
"in": "$$this.importer"
}
}
}
}, {
"$lookup": {
from: 'businesses',
localField: 'importers_id',
foreignField: '_id',
as: 'importers_id'
}
}, {
"$addFields": {
"countries_id": {
"$reduce": {
"input": "$importers_id",
"initialValue": [],
"in": "$$this.country"
}
}
}
}, {
"$lookup": {
from: 'countries',
localField: 'countries_id',
foreignField: '_id',
as: 'countries_id'
}
}, {
"$addFields": {
"importers_id": {
"$map": {
"input": '$importers_id',
"as": "businessI",
"in": {
"$mergeObjects": [
"$$businessI",
{
"country": {
"$arrayElemAt": [
"$countries_id",
{ "$indexOfArray": ["$countries_id", "$$businessI.country"] }
]
}
}
]
}
}
}
}
}, {
"$addFields": {
"labels_id": {
"$reduce": {
"input": "$productsList",
"initialValue": [],
"in": "$$this.labeled"
}
}
}
}, {
"$lookup": {
from: 'labels',
localField: 'labels_id',
foreignField: '_id',
as: 'labels_id'
}
}, {
"$addFields": {
"productsList": {
"$map": {
"input": "$productsList",
"as": "productList",
"in": {
"$mergeObjects": [
"$$productList",
{
"product": {
"$arrayElemAt": [
"$products_id",
{ "$indexOfArray": ["$products_id", "$$productList.product"] }
]
}
},
{
"exporter": {
"$arrayElemAt": [
"$exporters_id",
{ "$indexOfArray": ["$exporters_id", "$$productList.exporter"] }
]
}
},
{
"importer": {
"$arrayElemAt": [
"$importers_id",
{ "$indexOfArray": ["$importers_id", "$$productList.importer"] }
]
}
},
{
"labeled": {
"$arrayElemAt": [
"$labels_id",
{ "$indexOfArray": ["$labels_id", "$$productList.labeled"] }
]
}
}
]
}
}
}
}
}, {
"$project": { "products_id": 0, "exporters_id": 0, "importers_id": 0, "labels_id": 0, "countries_id": 0 }
}, {
"$lookup": {
from: 'businesses',
localField: 'business',
foreignField: '_id',
as: 'business'
}
}, {
"$unwind": {
"path":'$business',
"preserveNullAndEmptyArrays":true
}
}, {
"$lookup": {
from: 'countries',
localField: 'business.country',
foreignField: '_id',
as: 'business.country'
}
}, {
"$unwind": {
"path":'$business.country',
"preserveNullAndEmptyArrays":true
}
}, {
"$lookup": {
from: 'statemovements',
localField: 'actualState',
foreignField: '_id',
as: 'actualState'
}
}, {
"$unwind": {
"path":'$actualState',
"preserveNullAndEmptyArrays":true
}
}, {
"$lookup": {
from: 'thermographs',
localField: 'thermograph',
foreignField: '_id',
as: 'thermograph'
}
}, {
"$unwind": {
"path":'$thermograph',
"preserveNullAndEmptyArrays":true
}
}, {
"$lookup": {
from: 'businesses',
localField: 'internalDestination',
foreignField: '_id',
as: 'internalDestination'
}
}, {
"$unwind": {
"path":'$internalDestination',
"preserveNullAndEmptyArrays":true
}
}, {
"$lookup": {
from: 'countries',
localField: 'internalDestination.country',
foreignField: '_id',
as: 'internalDestination.country'
}
}, {
"$unwind": {
"path":'$internalDestination.country',
"preserveNullAndEmptyArrays":true
}
}, {
"$lookup": {
from: 'countries',
localField: 'externalDestination',
foreignField: '_id',
as: 'externalDestination'
}
}, {
"$unwind": {
"path":'$externalDestination',
"preserveNullAndEmptyArrays":true
}
}
]
现在,问题是我无法为movements
. 我完成这项工作的唯一方法是放置outMovements
管道,但它会在对象中产生不必要的步骤,如果不存在则inMovement
留下一个空白。internalDestination
我一直无法找到一种方法来区分不同的文档并使用正确的管道。
解决方案
推荐阅读
- google-calendar-api - 全天活动默认为“忙碌”
- javascript - Mongo db排序计算
- android-studio - Android Studio,如何在 Material Theme 中更改左侧面板字体大小
- java - 处理 bean 注册时出错 [io.micronaut.rabbitmq.intercept.RabbitMQConsumerAdvice]
- javascript - JavaScript箭头函数问题,语法问题
- reactjs - 高阶组件中功能组件的道具
- python - 如何制作一个可点击的图像,给我点击的坐标?
- java - BufferedReader 在存储中找不到文本文件
- c# - 我将如何跟踪赛车游戏中玩家和 AI 的位置?
- ruby-on-rails - 如何从已安装的 Spree gem 的控制器中扩展我的控制器?