Javascript Mongodb获取所有集合项上的arrayitems计数
我有这样一个mongodb系列:Javascript Mongodb获取所有集合项上的arrayitems计数,javascript,mongodb,Javascript,Mongodb,我有这样一个mongodb系列: { _id: 123, name: 'some name', category: 17, sizes: ['XS', 'S', 'XL'] }, { _id: 124, name: 'another name', category: 17, sizes: ['S', 'L', '2XL'] } 我需要两种不同的方法。第一个问题:在一个特定的类别中,每种尺寸有多少个项目可用 { 17: {
{
_id: 123,
name: 'some name',
category: 17,
sizes: ['XS', 'S', 'XL']
},
{
_id: 124,
name: 'another name',
category: 17,
sizes: ['S', 'L', '2XL']
}
我需要两种不同的方法。第一个问题:在一个特定的类别中,每种尺寸有多少个项目可用
{
17: {
XS: 0,
S: 19,
M: 100
},
39: {
XS: 5,
...
}
}
也可以采用一种解决方案,仅显示该尺寸的物品是否可用:
{
17: {
XS: false,
S: true,
M: true,
...
},
39: {
XS: true,
...
}
}
第二个问题:我需要相同的,但在对名称执行全文搜索之后
我已经尝试过在这些字段上进行转换,但对于如何在阵列上执行转换,我有点不知所措
谢谢你的帮助
更新: 在来自的帮助下,我更进一步:
db.so.aggregate(
[
// First, filter by name or something else
// this could also include the category
{
$match: {
'name': {
$regex: /other.*/i
}
}
},
// explode the sizes-array into single documents
{ '$unwind': '$sizes' },
// group and count
{ '$group': {
'_id': '$sizes',
'count': { '$sum': 1 }
}}
]
)
仍然缺少:按类别执行此操作以下是我插入的一些示例数据:
/* 1 */
{
"_id" : 123,
"name" : "some name",
"category" : 17,
"sizes" : [
"XS",
"S",
"XL"
]
}
/* 2 */
{
"_id" : 124,
"name" : "another name",
"category" : 17,
"sizes" : [
"S",
"L",
"2XL"
]
}
/* 3 */
{
"_id" : 125,
"name" : "name",
"category" : 35,
"sizes" : [
"S",
"L",
"2XL"
]
}
用例1
在您的第一个用例中,您似乎希望按照大小和类别进行分组。实际上,您可以按多个键进行分组,下面是一个示例:
db.so.aggregate([
// add your match here...
{
'$unwind': '$sizes' // flatten your array
},
// group and count
{
'$group': {
'_id': {
sizes: '$sizes',
category: '$category'
}, // group by both sizes and category
'count': {
'$sum': 1
},
}
},
{
'$group': {
'_id': '$category', // group by category now
sizeCount: { // create an array that includes the size and the count for that size
$push: {
size: "$sizes",
count: "$count"
}
}
}
}
])
此管道将创建以下结果:
{
"_id" : 17,
"sizeCount" : [
{
"size" : "2XL",
"count" : 1.0
},
{
"size" : "XS",
"count" : 1.0
},
{
"size" : "S",
"count" : 2.0
},
{
"size" : "XL",
"count" : 1.0
},
{
"size" : "L",
"count" : 1.0
}
]
}
你能接受吗
用例2
现在,关于您的第二个用例,您希望如何对该类别中甚至不存在的大小进行分组?
但一般来说,您可以通过使用
因此,在同一示例中,如果应用此管道:
db.so.aggregate([
// add your match here ...
{
'$unwind': '$sizes' // flatten your array
},
// group and count
{
'$group': {
'_id': {
sizes: '$sizes',
category: '$category'
}, // group by both sizes and category
'count': {
'$sum': 1
},
}
},
{
'$project': {
_id: 0,
'count': {
$cond: [{
$eq: ["$count", 1.0]
}, "Limited", "Many"]
},
category: "$_id.category",
sizes: "$_id.sizes"
}
},
{
'$group': {
'_id': '$category',
sizeCount: {
$push: {
size: "$sizes",
count: "$count"
}
}
}
}
])
它将产生以下结果(一个示例):
所以基本上在这行中,$cond:[{$eq:[“$count”,1.0]},“Limited”,“Many”]}
我们说,如果
count
字段仅为1.0,那么该尺寸的衬衫是有限的,否则我们有很多。您可以应用任何比较运算符,因此还可以执行以下操作:$cond:[{$lte:[“$count”,2.0]},“Limited”,“Many”]}
以下是我插入的一些示例数据:
/* 1 */
{
"_id" : 123,
"name" : "some name",
"category" : 17,
"sizes" : [
"XS",
"S",
"XL"
]
}
/* 2 */
{
"_id" : 124,
"name" : "another name",
"category" : 17,
"sizes" : [
"S",
"L",
"2XL"
]
}
/* 3 */
{
"_id" : 125,
"name" : "name",
"category" : 35,
"sizes" : [
"S",
"L",
"2XL"
]
}
用例1
在您的第一个用例中,您似乎希望按照大小和类别进行分组。实际上,您可以按多个键进行分组,下面是一个示例:
db.so.aggregate([
// add your match here...
{
'$unwind': '$sizes' // flatten your array
},
// group and count
{
'$group': {
'_id': {
sizes: '$sizes',
category: '$category'
}, // group by both sizes and category
'count': {
'$sum': 1
},
}
},
{
'$group': {
'_id': '$category', // group by category now
sizeCount: { // create an array that includes the size and the count for that size
$push: {
size: "$sizes",
count: "$count"
}
}
}
}
])
此管道将创建以下结果:
{
"_id" : 17,
"sizeCount" : [
{
"size" : "2XL",
"count" : 1.0
},
{
"size" : "XS",
"count" : 1.0
},
{
"size" : "S",
"count" : 2.0
},
{
"size" : "XL",
"count" : 1.0
},
{
"size" : "L",
"count" : 1.0
}
]
}
你能接受吗
用例2
现在,关于您的第二个用例,您希望如何对该类别中甚至不存在的大小进行分组?
但一般来说,您可以通过使用
因此,在同一示例中,如果应用此管道:
db.so.aggregate([
// add your match here ...
{
'$unwind': '$sizes' // flatten your array
},
// group and count
{
'$group': {
'_id': {
sizes: '$sizes',
category: '$category'
}, // group by both sizes and category
'count': {
'$sum': 1
},
}
},
{
'$project': {
_id: 0,
'count': {
$cond: [{
$eq: ["$count", 1.0]
}, "Limited", "Many"]
},
category: "$_id.category",
sizes: "$_id.sizes"
}
},
{
'$group': {
'_id': '$category',
sizeCount: {
$push: {
size: "$sizes",
count: "$count"
}
}
}
}
])
它将产生以下结果(一个示例):
所以基本上在这行中,$cond:[{$eq:[“$count”,1.0]},“Limited”,“Many”]}
我们说,如果
count
字段仅为1.0,那么该尺寸的衬衫是有限的,否则我们有很多。您可以应用任何比较运算符,因此还可以执行以下操作:$cond:[{$lte:[“$count”,2.0]},“Limited”,“Many”]}
注意:投影将很快添加
你可以
展开
->按类别和大小分组
->按类别分组并推送
->项目
请参考以下查询。这将给出一个没有任何投影的结果。我会很快添加投影以符合您的要求
var group_by_category_and_sizes = {
"$group": {
"_id": {
"category": "$category",
"size": "$sizes"
},
"count": {
"$sum": 1
}
}
}
var group_by_category_and_push = {
"$group": {
"_id": {
"category": "$_id.category"
},
"combine": {
"$push": { "size": "$_id.size", "count": "$count" }
}
}
}
db.clothings.aggregate([{ "$unwind": "$sizes" }, group_by_category_and_sizes, group_by_category_and_push])
文件
{name:'some name',类别:17,大小:['XS','S','XL']}
{name:'other name',类别:17,大小:['S','L','2XL']}
{name:'other name',类别:18,大小:['M','S','L']}
这将产生
{
"_id": {
"category": 18
},
"combine": [{
"size": "L",
"count": 1
}, {
"size": "S",
"count": 1
}, {
"size": "M",
"count": 1
}]
} {
"_id": {
"category": 17
},
"combine": [{
"size": "2XL",
"count": 1
}, {
"size": "S",
"count": 2
}, {
"size": "XL",
"count": 1
}, {
"size": "L",
"count": 1
}, {
"size": "XS",
"count": 1
}]
}
注意:投影将很快添加 你可以
展开
->按类别和大小分组
->按类别分组并推送
->项目
请参考以下查询。这将给出一个没有任何投影的结果。我会很快添加投影以符合您的要求
var group_by_category_and_sizes = {
"$group": {
"_id": {
"category": "$category",
"size": "$sizes"
},
"count": {
"$sum": 1
}
}
}
var group_by_category_and_push = {
"$group": {
"_id": {
"category": "$_id.category"
},
"combine": {
"$push": { "size": "$_id.size", "count": "$count" }
}
}
}
db.clothings.aggregate([{ "$unwind": "$sizes" }, group_by_category_and_sizes, group_by_category_and_push])
文件
{name:'some name',类别:17,大小:['XS','S','XL']}
{name:'other name',类别:17,大小:['S','L','2XL']}
{name:'other name',类别:18,大小:['M','S','L']}
这将产生
{
"_id": {
"category": 18
},
"combine": [{
"size": "L",
"count": 1
}, {
"size": "S",
"count": 1
}, {
"size": "M",
"count": 1
}]
} {
"_id": {
"category": 17
},
"combine": [{
"size": "2XL",
"count": 1
}, {
"size": "S",
"count": 2
}, {
"size": "XL",
"count": 1
}, {
"size": "L",
"count": 1
}, {
"size": "XS",
"count": 1
}]
}
以下是您如何获得建议的确切输出文档:
db.so.aggregate({
$unwind: "$sizes" // flatten the sizes array
}, {
$group: {
_id: { // group by both category and sizes
category: "$category",
size: "$sizes"
},
count: {
$sum: 1 // count number of documents per bucket
}
}
}, {
$group: {
_id: "$_id.category", // second grouping to get entries per category
sizes: {
$push: { k: "$_id.size", v: "$count" } // create an array of key/value pairs which we will need in this exact shape in the next stage
}
}
}, {
$project: {
"magic": {
$arrayToObject: // transform the key/value pair we generate below into a document
[[{
// the $substr is a hack to transform the numerical category (e.g. 17)
// into a string (not nice, probably not supported but working for now...)
// which is needed for the above $arrayToObject to work
k: { $substr: [ "$_id", 0, -1 ] },
v: {
$arrayToObject: "$sizes" // turn the key/value pairs we created in the previous pipeline stage into a document
}
}]]
}
}
}, {
$replaceRoot: {
newRoot: "$magic" // promote our "magic" field to the document root
}
})
请注意,虽然这为您提供了正确的输出,但我不一定建议您走这条路线,因为聚合管道相当庞大,内置了相当多的魔法,几乎没有什么可测量的好处。因此,如果您可以接受@Alex P建议的输出结构,那么这肯定会更容易理解和维护,也会更快
关于第二个场景:您可以在
$unwind
阶段之前添加任意数量的初步$match阶段,以过滤掉任何多余的数据。以下是您可以获得建议的确切输出文档的方法:
db.so.aggregate({
$unwind: "$sizes" // flatten the sizes array
}, {
$group: {
_id: { // group by both category and sizes
category: "$category",
size: "$sizes"
},
count: {
$sum: 1 // count number of documents per bucket
}
}
}, {
$group: {
_id: "$_id.category", // second grouping to get entries per category
sizes: {
$push: { k: "$_id.size", v: "$count" } // create an array of key/value pairs which we will need in this exact shape in the next stage
}
}
}, {
$project: {
"magic": {
$arrayToObject: // transform the key/value pair we generate below into a document
[[{
// the $substr is a hack to transform the numerical category (e.g. 17)
// into a string (not nice, probably not supported but working for now...)
// which is needed for the above $arrayToObject to work
k: { $substr: [ "$_id", 0, -1 ] },
v: {
$arrayToObject: "$sizes" // turn the key/value pairs we created in the previous pipeline stage into a document
}
}]]
}
}
}, {
$replaceRoot: {
newRoot: "$magic" // promote our "magic" field to the document root
}
})
请注意,虽然这为您提供了正确的输出,但我不一定建议您走这条路线,因为聚合管道相当庞大,内置了相当多的魔法,几乎没有什么可测量的好处。因此,如果您可以接受@Alex P建议的输出结构,那么这肯定会更容易理解和维护,也会更快
关于第二个场景:您可以在
$unwind
阶段之前添加任意数量的初步$match阶段,以过滤掉任何多余的数据。您可以这样做:[{'$unwind':'$sizes'},{'$group':{'\u id':{'size':'$sizes',category':'$category'},'count':{'$sum':1}}}]要生成如下文档:{“\u id”:{“size”:“XS”,“category”:17},“count”:1.0}您可以这样做:[{'$unwind':'$sizes'},{'$group':{''u id':{'size':'$sizes','category':'$category'},'count':{'$sum':1}}}]生成如下文档:{“_id”:{“size”:“XS”,“category”:17},“count”:1.0}