У меня есть приложение nodejs express с API для возврата данных из базы данных mongodb. Это моя мангуста модель:
const bookingSchema = new mongoose.Schema({
timestamp: {
type: Date,
default: Date.now,
required: true
},
tags: {
type: [String],
required: true
},
amount: {
type: Number,
required: true
},
type: {
type: String,
required: true,
enum: ['expense', 'income']
}
})
Когда я вызываю API с путем /api/bookings/listbymonth/2019/1
, эта функция внутри бэкэнда вызывается:
const bookingsListByMonth = (req, res) => {
const year = ("0000" + req.params.year).slice(-4)
const month = ("0000" + req.params.month).slice(-2)
const dateOfMonth = `${year}${month}01`
const start = moment(dateOfMonth).startOf("month")
const end = moment(dateOfMonth).endOf("month")
bookingMongooseModel
.find({
timestamp: {
$gt: start,
$lt: end
}
})
.sort({ timestamp: 1 })
.exec((err, bookings) => {
if (!bookings) {
return res
.status(404)
.json({
"message": "booking not found"
})
} else if (err) {
return res
.status(404)
.json(err)
}
res
.status(200)
.json(processBookings(bookings));
})
}
Вместо того, чтобы просто возвращать данные json, я хочу предварительно обработать данные и создать хорошее поле метки времени и валюты. Вот почему данные json проходят через дополнительную функцию processBookings
. Для тестирования я попытался добавить еще одно поле timestamp2: 123
:
const processBookings = (bookings) => {
console.log("Bookings unsorted: \n" + bookings + "\n")
const mainTags = [
"Essen",
"Essen gehen",
"Notwendiges",
"Luxus",
]
let bookingsProcessed = []
mainTags.forEach((tag) => {
let singleTagBookings = bookings.filter(
booking => booking.tags.includes(tag)
)
singleTagBookings.map((item) => {
item.timestamp2 = "123"
return item
})
let message = null;
if (singleTagBookings.length === 0) {
message = "No bookings found";
}
bookingsProcessed.push({
name: tag,
bookings: singleTagBookings,
message: message
})
});
console.log("Bookings sorted:")
bookingsProcessed.forEach((item) => {
console.log(item)
})
return bookingsProcessed
}
Объекты в массиве bookings
должны иметь другое свойство timestamp2: "123"
, но они не имеют. Вот вывод:
Bookings unsorted:
{ tags: [ 'Luxus', 'voluptatem', 'atque', 'qui', 'sunt' ],
_id: 5cb2c9e1ff6c9c6bef95f56f,
timestamp: 2019-01-06T08:53:06.945Z,
amount: 68.02,
type: 'expense',
__v: 0 },{ tags: [ 'Essen gehen', 'ut', 'unde', 'et', 'officiis' ],
_id: 5cb2c9e1ff6c9c6bef95f56e,
timestamp: 2019-01-09T20:35:06.411Z,
amount: 33.77,
type: 'income',
__v: 0 }
Bookings sorted:
{ name: 'Essen', bookings: [], message: 'No bookings found' }
{ name: 'Essen gehen',
bookings:
[ { tags: [Array],
_id: 5cb2c9e1ff6c9c6bef95f56e,
timestamp: 2019-01-09T20:35:06.411Z,
amount: 33.77,
type: 'income',
__v: 0 } ],
message: null }
{ name: 'Notwendiges',
bookings: [],
message: 'No bookings found' }
{ name: 'Luxus',
bookings:
[ { tags: [Array],
_id: 5cb2c9e1ff6c9c6bef95f56f,
timestamp: 2019-01-06T08:53:06.945Z,
amount: 68.02,
type: 'expense',
__v: 0 } ],
message: null }
Как и предлагалось в комментариях, я пытался использовать let bookings = [ {tags: ["Essen"]}];
в качестве тестовых данных. Здесь это работает. Выход:
Bookings unsorted:
[object Object]
Bookings sorted:
{ name: 'Essen',
bookings: [ { tags: [Array], timestamp2: '123' } ],
message: null }
{ name: 'Essen gehen',
bookings: [],
message: 'No bookings found' }
{ name: 'Notwendiges',
bookings: [],
message: 'No bookings found' }
{ name: 'Luxus', bookings: [], message: 'No bookings found' }
Так что я предполагаю, что это как-то связано с моей моделью мангуста, ограничивающей добавление дополнительного поля. Однако, если я поставлю
console.log("EXTENSIBLE " + Object.isExtensible(bookings))
res
.status(200)
.json(processBookings(bookings));
в мою bookingsListByMonth
функцию я получаю:
EXTENSIBLE true
То есть теоретически я должен иметь возможность что-то добавить к объекту bookings
?
В качестве обходного пути я добавил поле timestamp2
к своей модели мангуста:
const bookingSchema = new mongoose.Schema({
timestamp: {
type: Date,
default: Date.now,
required: true
},
timestamp2: {
type: String,
default: null
},
tags: {
type: [String],
required: true
},
amount: {
type: Number,
required: true
},
type: {
type: String,
required: true,
enum: ['expense', 'income']
}
})
Это работает, однако оно добавляет дополнительное бесполезное поле данных в мою базу данных. Как я могу изменить объект bookings
json, возвращенный из mongodb? Если я не могу изменить его, потому что это модель Мангуста, как я могу сделать копию, которую можно редактировать?