Итак, это мои модели
let restaurantSchema = mongoose.Schema({
name: 'string',
restId: 'string',
saved: {type: 'date', default: Date.now()}
})
let userSchema = mongoose.Schema({
firstName: {type: 'string', default: ''},
lastName: {type: 'string', default: ''},
username: {
type: 'string',
required: true,
unique: true
},
beenTo: [restaurantSchema],
toGoTo: [restaurantSchema]
})
Я хочу сделать канал: «пользователь А хочет пойти в ресторан X, пользователь Б хочет пойти в ресторан Y, пользователь А был в ресторане Z» и т. д., все отсортировано в первую очередь по дате. поэтому я пытался использовать агрегат для создания документов, содержащих имя пользователя и название ресторана, а также метку времени, чтобы я мог сортировать все документы, независимо от имени пользователя, с помощью {'сохранено': -1 } или любой другой временной меткой.
Вот о том, что у меня есть до сих пор
User.aggregate([
{$match: {username: {$ne: username}}},
{$lookup: {
from: "restaurants",
localField: "beenTo.saved",
foreignField: "saved",
as: "savRest"
}},
{$project: {'savRest.saved': 1, 'savRest.name': 1, 'username': 1}},
{$group: {
_id: null,
sav: {$push: '$savRest.saved'}
}}
])
Учитывая массивы, я ожидаю, что в какой-то момент мне нужно будет размотать $, но я не уверен, где в конвейере это идет...
Понимаю. Извините, если это сбивает с толку, я пытаюсь понять большую часть этого сам. В этом случае, предположим, я внес предложенное изменение в свою схему, смогу ли я получить желаемый результат?
Да, вы можете, пожалуйста, скажите мне, что именно вы хотите, и я помогу вам. чего вы пытаетесь достичь с помощью конвейера агрегации?
В конечном итоге я хочу отсортировать все записи во всех (других) массивах пользователей beTo и toGoTo по дате, начиная с самой последней.
Итак, вам нужны все пользователи, кроме данного пользователя, поэтому вы написали: username : {$ne : username} верно?.

Я думаю, вам нужно реструктурировать свой schema и включить в пользовательский документ только ресторан _id, а не хранить весь ресторан doc как sub-document.
Пожалуйста, измените свой userSchema на это:
let userSchema = mongoose.Schema({
firstName: {type: 'string', default: ''},
lastName: {type: 'string', default: ''},
username: {
type: 'string',
required: true,
unique: true
},
beenTo: [{type : mongoose.Schema.Types.ObjectId,ref : "Restaurant"}],
toGoTo: [{type : mongoose.Schema.Types.ObjectId,ref : "Restaurant"}]
})
Посмотрите изменение, которое я внес в вашу схему: вместо сохранения документа ресторана мы будем хранить только его _id (ObjectId).
А чтобы получить все рестораны и отсортировать их, вы можете сделать следующее:
User.aggregate([
{$match: {username: {$ne: username}}},
// need to unwind the array, before we can do a $lookup over it
{$unwind : "beenTo"},
{$lookup: {
from: "restaurants",
localField: "beenTo",
foreignField: "_id",
as: "beenTo"
}},
//need to unwind again, as $lookup returns an array
{$unwind : "beenTo"},
//sort the result by beenTo.saved (date) first.
{$sort : {"$beenTo.saved" : -1}},
//after sorting, group all the docs and created sorted beenTo array
{
$group : {
_id : "$_id",
firstName : {$first : "$firstName"},
lastName : {$first : "$lastName"},
username : {$first : "$username"},
beenTo : {$push : "$beenTo"},
toGoTo : {$first : "$toGoTo"}
}
},
//after sorting of beenTo, we can go for sorting of toGoTo array,
// we will follow the same procedure again.
{$unwind : "toGoTo"},
{$lookup: {
from: "restaurants",
localField: "toGoTo",
foreignField: "_id",
as: "toGoTo"
}},
//need to unwind again, as $lookup returns an array
{$unwind : "toGoTo"},
{$sort : {"$toGoTo.saved" : -1}},
{
$group : {
_id : "$_id",
firstName : {$first : "$firstName"},
lastName : {$first : "$lastName"},
username : {$first : "$username"},
beenTo : {$first : "$beenTo"}
toGoTo : {$push : "$toGoTo"},
}
}
])
Объяснение конвейера агрегации:
$match: требуется для соответствия всем выбранным документам.$unwind: нам нужно раскрутить массив (beenTo), прежде чем мы сможем выполнить поиск по нему.$lookup : заполнил уважаемый документ ресторана из коллекции ресторанов.$unwind : $lookup возвращает массив, нам нужно снова преобразовать его в объект.$sort: отсортировать все документы по beenTo.saved значению$group: сгруппируйте все документы на основе _id пользователей и поместите все beenTo документы в свой массив. (Теперь у нас есть массив beenTo, заполненный документами ресторана и отсортированный)$unwind : Далее нам нужно раскрутить массив toGoTo, чтобы мы могли выполнить его поиск$lookup: для заполнения соответствующих документов из коллекции ресторана.$unwind : Опять нам нужно раскрутиться, так как $lookup возвращает массив$sort: отсортировать все документы в соответствии с полем toGoTo.saved.$group: сгруппируйте все документы на основе пользователей _id и поместите все документы toGoTo в свой массив, а beenTo останется прежним.Следовательно, в конце 11-го шага все документы с beenTo и toGoTo будут заполнены и отсортированы по дате сохранения.
Я надеюсь, что это помогает вам.
Примечание: при добавлении ресторанов в массив beenTo и toGoTo в документе пользователя нажимайте только restaurant's _id, а не весь doc.
Судя по вашей схеме, ресторан является поддокументом пользовательского документа
beenTo : [RestaurantSchema]. Это сохранит документ ресторана как поддокумент пользовательского объекта. В этом случае $lookup не будет работать так, как вы этого хотите. если вы хотите сохранить только идентификатор ресторана в массиве и ссылаться на фактический документ ресторана, вам нужно изменить свою схему:beenTo : [{type:mongoose.Schema.Types.Object, ref : 'Restaurant']. Если я неправильно понял ваш вопрос, пожалуйста, отредактируйте его, чтобы сделать его более понятным. Здесь немного запутанно.