我正在尝试使用MongoDB在Node.JS中创建一个简单的mediaserver用于它的后端。我将以下列方式将轨道元数据存储在MongoDB数据库中:
{
"_id" : ObjectId("53fadfb28024a9b42079820d"),
"title" : "Welcome To The Machine",
"artist" : [
"Pink Floyd"
],
"albumartist" : [ ],
"album" : "Wish You Were Here",
"year" : "1975",
"track" : {
"no" : 2,
"of" : 5
},
"genre" : [
"Rock"
],
"disk" : {
"no" : 0,
"of" : 0
},
"duration" : 446,
"filelocation" : "F:\\mediaserver\\Pink Floyd\\Wish You Were Here\\02 - Welcome To The Machine.m4a"
}
我想以下列方式提取艺术家,专辑和曲目信息:
[
{
artist: [ "someartist" ],
albums: [
{
title: "AlbumTitle",
tracks: [ "trackTitleOne", "trackTitleTwo" ]
}
]
},
{
artist: [ "second artist" ],
albums: [
{
title: "AlbumTitle 2",
tracks: [ "trackTitleOne", "trackTitleTwo" ]
}
]
}
]
我一直在mongo
shell中尝试不同的语句,而我最接近的是
db.testData.aggregate([
{
$group: {
_id: "$artist",
albums: { $addToSet: { title: "$album" } }
}
}
])
产生
{ "_id" : [ "Dave Brubeck" ], "albums" : [ { "title" : "Time Out" } ] }
{ "_id" : [ "Ian Hunter" ], "albums" : [ { "title" : "Welcome To The Club (disc 2)" }, { "title" : "Welcome To The Club (disc 1)" } ] }
{ "_id" : [ "The Band" ], "albums" : [ { "title" : "The Last Waltz <Complete Edition> (disc 2)" } ] }
{ "_id" : [ "Pink Floyd" ], "albums" : [ { "title" : "Wish You Were Here" }, { "title" : "Dark Side Of The Moon" } ] }
但正如您所看到的,该输出不包含任何曲目信息。我觉得像
这样的东西 db.testData.aggregate([
{
$group: {
_id: "$artist",
albums: { $addToSet: { title: "$album", tracks: { $push: "$title" } } }
}
}
])
可以做到这一点,但遗憾的是,这给我一个错误:
assert: command failed: {
"errmsg" : "exception: invalid operator '$push'",
"code" : 15999,
"ok" : 0
} : aggregate failed
Error: command failed: {
"errmsg" : "exception: invalid operator '$push'",
"code" : 15999,
"ok" : 0
} : aggregate failed
at Error (<anonymous>)
at doassert (src/mongo/shell/assert.js:11:14)
at Function.assert.commandWorked (src/mongo/shell/assert.js:244:5)
at DBCollection.aggregate (src/mongo/shell/collection.js:1149:12)
at (shell):1:13
2014-08-26T13:08:59.094+0200 Error: command failed: {
"errmsg" : "exception: invalid operator '$push'",
"code" : 15999,
"ok" : 0
} : aggregate failed at src/mongo/shell/assert.js:13
我也一直在检查这些手册,但它们似乎并没有包含任何关于如何执行这样一个复杂查询的线索。
(对不起,如果我在这里打破任何不成文的规则,这是我的第一篇文章。)
答案 0 :(得分:0)
我尝试用双$group
构建它,因为为什么不:
db.test.aggregate({$group : {_id: "$album" ,
artist: {$addToSet: "$artist"},
tracks:{$addToSet:"$title"}}},
{$group: {_id : "$artist",
albums:{$push: "$$ROOT"}}})
第一个制作专辑文档,第二个将艺术家分组。它生成表格
的文件{ "_id" : [ [ "Pink Floyd" ] ],
"albums" : [ { "_id" : "New Album",
"artist" : [ [ "Pink Floyd" ] ],
"tracks" : [ "Testtitle" ] },
{ "_id" : "Wish You Were Here",
"artist" : [ [ "Pink Floyd" ] ],
"tracks" : [ "Testtitle",
"Welcome To The Machine" ] } ] }
添加项目
{$project:{artist:"$_id","albums._id":1,"albums.tracks":1,_id:0}}
它产生
{ "artist" : [["Pink Floyd"]],
"albums" : [{"_id" : "New Album",
"tracks" : ["Testtitle"]},
{"_id" : "Wish You Were Here",
"tracks" : ["Testtitle",
"Welcome To The Machine"]
}]
}
不完全是您想要的(我无法将相册数组中的_id
重命名为title
,而不会严重行为不端,艺术家是双阵列)但也许是启动。
编辑:Trond Humborstad的最终解决方案
{ $group: { _id: {album: "$album", artist: "$artist"},
tracks: { $addToSet: { id: "$_id", title: "$title" }}}},
{ $group: { _id: "$_id.artist",
albums: { $addToSet: { title: "$_id.album", tracks: "$tracks" }}}}