#mongodb #go #aggregation-framework
#mongodb #Вперед #агрегация-фреймворк
Вопрос:
Я пытаюсь реализовать разбивку на страницы mongodb, и эта часть в порядке, я получил свой лимит и пропустил данные, НО я хотел получить общее количество своих элементов без повторного запроса.
Я использую aggregate с конвейером для заполнения некоторых данных, поэтому требуется использовать aggregate.
На самом деле я хотел бы расшифровать мой результат mongo примерно так:
type exemple struct {
Orders []Order
Total int
}
Я не знаю, возможно ли это без выполнения двух запросов, я попытался протестировать что-то вроде:
bson.D{
primitive.E{Key: "$facet", Value: bson.D{
primitive.E{Key: "orders", Value: []bson.D{
{primitive.E{Key: "$skip", Value: p.Skip}},
{primitive.E{Key: "$limit", Value: p.Limit}},
}},
primitive.E{Key: "totalCount", Value: []bson.D{
{primitive.E{Key: "$group", Value: bson.D{
primitive.E{Key: "_id", Value: nil},
primitive.E{Key: "count", Value: bson.D{
primitive.E{Key: "$sum", Value: 1},
}},
}}},
}},
}},
}
Это работает, но только декодирует :
type exemple struct {
Orders []Order `bson:"orders" json:"orders"`
TotalCount []map[string]interface{} `bson:"totalCount" json:"totalCount"`
}
и я должен декодировать с помощью []exemple как:
var test []exemple
if err = curs.All(r.ctx, amp;test); err != nil {
return err
}
Итак, чтобы получить мои данные, я должен выполнить некоторые fmt.Println(тест [0].totalCount) и это ужасно, поэтому я думаю, что есть лучший способ..
И я думаю, что понимаю a $ project, поэтому я бы воссоздал свои данные схемы, но это так привередливо и не очень приятно.
Я также пробовал это:
{primitive.E{Key: "$count", Value: "count"}},
{primitive.E{Key: "$skip", Value: p.Skip}},
{primitive.E{Key: "$limit", Value: p.Limit}},
Но эта попытка дает для каждых данных ключ подсчета для всех данных в моей БД.
Извините за этот неясный вопрос, я действительно не знаю, как правильно объяснить эту проблему, и, вероятно, это причина, по которой я не нахожу ответа.
——————— РЕДАКТИРОВАТЬ ———————
После тестов я нашел что-то работающее, но если у кого-то есть лучшее решение, я слушаю :
Я добавляю это в свой конвейер :
bson.D{
primitive.E{Key: "$facet", Value: bson.D{
primitive.E{Key: "orders", Value: []bson.D{
{primitive.E{Key: "$skip", Value: 10}},
{primitive.E{Key: "$limit", Value: 10}},
}},
primitive.E{Key: "totalCount", Value: []bson.D{
{primitive.E{Key: "$count", Value: "count"}},
}},
}},
}
и сопоставить результат агрегатной функции с :
resp := struct {
Orders []Order `bson:"orders" json:"orders"`
TotalCount []map[string]interface{} `bson:"totalCount" json:"totalCount"`
}{}
Моя ошибка до этого заключалась в использовании cursor.All() вместо цикла for для cursor.Next(), а затем декодирования (и соответственно) в цикл:
for curs.Next(r.ctx) {
if err = curs.Decode(amp;resp); err != nil {
log.Println(err)
}
}
теперь я могу работать со своим соответствующим, как и с соответствующим.Заказы или соответственно.Общее количество.
Но некоторые вопросы все еще здесь:
- могу ли я улучшить общее количество? Потому что на самом деле это интерфейс []map[string]{}, поэтому с ним легко работать.
Вывод: [карта [количество: 5]], ожидается: карта [количество: 5]
- для поиска другой коллекции я добавляю этот []bson.D к моему конвейеру (в моем случае)
[]bson.D{
{primitive.E{Key: "$lookup", Value: bson.D{primitive.E{Key: "from", Value: "users"}, primitive.E{Key: "localField", Value: "relationShip.customer"}, primitive.E{Key: "foreignField", Value: "_id"}, primitive.E{Key: "as", Value: "relationShip.included.customer"}}}},
{primitive.E{Key: "$unwind", Value: bson.D{primitive.E{Key: "path", Value: "$relationShip.included.customer"}, primitive.E{Key: "preserveNullAndEmptyArrays", Value: false}}}},
{primitive.E{Key: "$lookup", Value: bson.D{primitive.E{Key: "from", Value: "users"}, primitive.E{Key: "localField", Value: "relationShip.editor"}, primitive.E{Key: "foreignField", Value: "_id"}, primitive.E{Key: "as", Value: "relationShip.included.editor"}}}},
{primitive.E{Key: "$unwind", Value: bson.D{primitive.E{Key: "path", Value: "$relationShip.included.editor"}, primitive.E{Key: "preserveNullAndEmptyArrays", Value: false}}}},
}
это работает, НО я добавляю это ПЕРЕД разбиением на страницы, поэтому mongodb ищет всю коллекцию? Можно добавить его после разбиения на страницы для, возможно, повышения производительности?
Комментарии:
1. Вы хотите изменить
[]map[string]interface{}
наint
?2. Привет @ttrasn Я отредактировал свой вопрос с помощью «решения», возможно, это поможет вам понять