如何解决在MongoDB中按数组排序时忽略空值
我有以下文档的MongoDB集合items
:
{ "values" : [1,2] }
{ "values" : [5,null] }
{ "values" : [-5,null] }
是否可以通过没有values
值的null
属性对该集合进行排序?我当前的查询是:
db.items.aggregate([{"$sort": {"values": 1}}])
结果如下:
{ "values" : [5,null] }
{ "values" : [1,2] }
第一个值为[5,null]
和[-5,null]
,因为null
是集合中的最小值。但是,我想忽略空值,仅按数字排序,所以:
{ "values" : [-5,null] }
如果没有数字(两个值均为null
),则文档应排在最后。
解决方法
您可以尝试一下
-
$addFields
使用values_clone
在values
中创建$map
的{{1}},将null
替换为字符串"null"
,因为当我们排序时它将排在最后
db.collection.aggregate([
{
$addFields: {
values_clone: {
$map: {
input: "$values",as: "v",in: {
$cond: {
if: { $eq: ["$$v",null] },then: "null",else: "$$v"
}
}
}
}
}
},
-
$sort
以values_clone
升序
{ $sort: { values_clone: 1 } },
-
$project
隐藏values_clone
{ $project: { values_clone: 0 } }
])
,
您可以使用以下阶段
db.collection.aggregate([
{
$unwind: "$values" //unwind them to skip null values
},{
$match: {
"values": { //skip null values
$ne: null
}
}
},{
"$sort": { //sorting pipeline
"values": 1
}
},{
$group: { //regrouping them
"_id": "$_id","values": {
$push: "$values"
}
}
}
])
如果即使一个值为null也要忽略完整的数组,则可以跳过unwind
和group
阶段。
其他替代方法:
解决方案1::如果不需要保留数组本身中的所有null
值[]或null
字段。
使用$filter
过滤掉不为空元素,(所有null
元素)数组将为空,使用$match
从文档中过滤掉,然后values
上的$sort
。
db.collection.aggregate([
{
$project: {
values: {
$filter: {
input: "$values",as: "d",cond: {
$ne: [
"$$d",null
]
}
}
}
}
},{
$match: {
"values": {
$ne: []
}
}
},{
"$sort": {
"values": 1
}
}
]);
解决方案2: IMO并不是一个好方法。但是可以完成工作并按原样保留文档和null
值。
首先将null
的值转换为"null"
的字符串,以使$sort
的顺序根据字段类型起作用。使用$map
"null"
字符串转换回null
db.collection.aggregate([
{
$project: {
values: {
$map: {
input: "$values",in: {
$cond: {
if: {
$eq: [
"$$d",null
]
},else: "$$d"
}
}
}
}
}
},{
"$sort": {
"values": 1
}
},{
$project: {
values: {
$map: {
input: "$values","null"
]
},then: null,else: "$$d"
}
}
}
}
}
}
]);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。