#mongodb #aggregation-framework
#mongodb #структура агрегации
Вопрос:
У нас есть вложенный документ и мы пытаемся сгруппировать по элементу массива. Наша структура документа выглядит следующим образом
/* 1 */
{
"_id" : ObjectId("5a690a4287e0e50010af1432"),
"slug" : [
"true-crime-the-10-most-infamous-american-murder-mysteries",
"10-most-infamous-american-murder-mysteries"
],
"tags" : [
{
"id" : "59244aa6b1be5055278e9b5b",
"name" : "true crime",
"_id" : "59244aa6b1be5055278e9b5b"
},
{
"id" : "5924524db1be5055278ebd6e",
"name" : "Occult Museum",
"_id" : "5924524db1be5055278ebd6e"
},
{
"id" : "5a690f0fc1a72100110c2656",
"_id" : "5a690f0fc1a72100110c2656",
"name" : "murder mysteries"
},
{
"id" : "59244d71b1be5055278ea654",
"name" : "unsolved murders",
"_id" : "59244d71b1be5055278ea654"
}
]
}
Мы хотим найти список всех групп слизней по имени тега. Я пытаюсь следовать, и он получает результат, но он неточный. У нас есть сотни записей с каждым тегом, но я получаю только несколько с моим запросом. Я не уверен, что я здесь делаю не так.
Заранее спасибо.
// Requires official MongoShell 3.6
db.getCollection("test").aggregate(
[
{
"$match" : {
"item_type" : "Post",
"site_id" : NumberLong(2),
"status" : NumberLong(1)
}
},
{$unwind: "$tags" },
{
"$group" : {
"_id" : {
"tags᎐name" : "$tags.name",
"slug" : "$slug"
}
}
},
{
"$project" : {
"tags.name" : "$_id.tags᎐name",
"slug" : "$_id.slug",
"_id" : NumberInt(0)
}
}
],
{
"allowDiskUse" : true
}
);
Ожидаемый результат
TagName Slug
----------
true crime "true-crime-the-10-most-infamous-american-murder-mysteries",
"10-most-infamous-american-murder-mysteries"
"All records where tags true crime"
Комментарии:
1. можете ли вы обновить вопрос ожидаемым результатом запроса, который вы хотите?
Ответ №1:
Вместо того, чтобы использовать slug
как часть _id
, вы должны использовать $ push или $ addToSet для их накопления, попробуйте:
db.test.aggregate([
{
$unwind: "$tags"
},
{
$unwind: "$slug"
},
{
$group: {
_id: "$tags.name",
slugs: { $addToSet: "$slug" }
}
},
{
$project: {
_id: 1,
slugs: {
$reduce: {
input: "$slugs",
initialValue: "",
in: {
$concat: [ "$$value", ",", "$$this" ]
}
}
}
}
}
])
РЕДАКТИРОВАТЬ: чтобы получить строку, разделенную запятыми, для слизней, вы можете использовать $reduce с $concat
Вывод:
{ "_id" : "murder mysteries", "slugs" : ",10-most-infamous-american-murder-mysteries,true-crime-the-10-most-infamous-american-murder-mysteries" }
{ "_id" : "Occult Museum", "slugs" : ",10-most-infamous-american-murder-mysteries,true-crime-the-10-most-infamous-american-murder-mysteries" }
{ "_id" : "unsolved murders", "slugs" : ",10-most-infamous-american-murder-mysteries,true-crime-the-10-most-infamous-american-murder-mysteries" }
{ "_id" : "true crime", "slugs" : ",10-most-infamous-american-murder- mysteries,true-crime-the-10-most-infamous-american-murder-mysteries" }
Комментарии:
1. Это почти то, что мне нужно. Есть ли способ использовать slug в виде строки, разделенной запятой, а не массива? Мне нужно экспортировать эти данные в Excel, и это создает ненужные пустые столбцы
2. @jvm изменил мой ответ