我正在尝试下面的聚合,但似乎没有使用 $ ne 和 null 获得预期的结果。
我尝试了其他解决方案,例如使用 $ cond , $ not 和 $ eq 的组合无济于事。使用 $ gt:[“$ unloadeddate”,null] 似乎给出了一些结果,但这似乎不是正确的语法,我担心在整个数据集上正确运行并不值得信赖。
另外,查询如下:
db.getCollection('esInvoices').find({"esBlendTickets.loadeddate":{$ne:null}})
...返回结果,因此不确定为什么聚合函数中的相同查询无效。
任何帮助表示赞赏!!
第一部分有效......
"unloadeddate": { "$switch": {
branches:[ {
case: {
"$ne":[ "$esBlendTickets.ticketdate", null]
},
then: "$esBlendTickets.ticketdate"
}, {
case: {
"$ne":[ "$esDeliveryTickets.ticketdate", null]
},
then: "$esDeliveryTickets.ticketdate"
}],
default: null
}
},
"loadeddate": { "$switch": {
branches:[ {
case: {
"$ne":[ "$esBlendTickets.loadeddate", null]
},
then: "$esBlendTickets.loadeddate"
}, {
case: {
"$ne":[ "$esDeliveryTickets.loadeddate", null]
},
then: "$esDeliveryTickets.loadeddate"
}],
default: null
}
},
...但是第二部分(除了结果值之外基本上是相同的逻辑)不能按预期工作......
"stagename": { "$switch": {
branches:[ {
case: {
"$ne":[ "$esDeliveryTickets.ticketdate", null]
},
then: "Invoiced"
}, {
case: {
"$ne":[ "$esBlendTickets.ticketdate", null]
},
then: "Invoiced"
}],
default: "Invoiced-Only"
}
}
完全聚合:
db.esInvoices.aggregate([ {
$addFields: {
// A single invoice will not have both a blend ticket and delivery ticket associated so looping tough each case should work.
"unloadeddate": { "$switch": {
branches:[ {
case: {
"$ne":[ "$esBlendTickets.ticketdate", null]
},
then: "$esBlendTickets.ticketdate"
}, {
case: {
"$ne":[ "$esDeliveryTickets.ticketdate", null]
},
then: "$esDeliveryTickets.ticketdate"
}],
default: null
}
},
"loadeddate": { "$switch": {
branches:[ {
case: {
"$ne":[ "$esBlendTickets.loadeddate", null]
},
then: "$esBlendTickets.loadeddate"
}, {
case: {
"$ne":[ "$esDeliveryTickets.loadeddate", null]
},
then: "$esDeliveryTickets.loadeddate"
}],
default: null
}
},
"stagedate": "$InvoiceHeader.InvDate",
"stagename": { "$switch": {
branches:[ {
case: {
"$ne":[ "$esDeliveryTickets.ticketdate", null]
},
then: "Invoiced"
}, {
case: {
"$ne":[ "$esBlendTickets.ticketdate", null]
},
then: "Invoiced"
}],
default: "Invoiced-Only"
}
}
}}])
答案 0 :(得分:0)
认为我刚遇到了与您同样的问题。目前正在使用Mongo 3.4。据我所知,在将其与$ne
进行比较时,查询 $ne
的行为与聚合 null
有所不同。把我甩了一下。
具体来说,当{ $ne: [ '$field', null ] }
为true
时,aggregate管道中的$field
谓词将返回undefined
。
但是,当使用queries(而不是$aggregate
)时,当{ field: { $ne: null }
为{{1}时,对于相同的文档,false
谓词将返回$field
}。
我的解决方法是在先前的步骤中将undefined
与$project
一起使用,以将该字段的{ field: { $ifNull: [ '$field': null ] } }
实例转换为显式undefined
,这将使合计null
根据需要工作。无论出于何种原因,$ifNull都可用于空,未定义和缺失的字段。不确定$ne
为何不同。
这是一个复制的例子。
$ne
答案 1 :(得分:0)
问题是缺少字段是 undefined
而 null
字段是空值。当您编写 "$ne":[ "$esDeliveryTickets.ticketdate", null]
时,您不会过滤前者,而只会过滤后者。
但是 undefined
比 null
“小”。为了过滤它们,您只需要制作 lte
/gt
而不是 eq
/ne
。所以这个查询返回所有现有的值:
参见示例:
db.test.insertOne(
{
"a" : 10,
"b" : null
})
...
db.getCollection('mytest').find( {},
{
"a" : { $lte : ["$a", null] },
"b" : { $lte : ["$b", null] },
"c" : { $lte : ["$c", null] },
})
// {
// "_id" : ObjectId("606724f38ec4d26b981b5a1c"),
// "a" : false,
// "b" : true,
// "c" : true
// }
就你而言:
"stagename": { "$switch": {
branches:[ {
case: {
"$gt":[ "$esDeliveryTickets.ticketdate", null]
},
then: "Invoiced"
}, {
case: {
"$gt":[ "$esBlendTickets.ticketdate", null]
},
then: "Invoiced"
}],
default: "Invoiced-Only"
}
}
而这个只返回缺失(或空)值:
"stagename": { "$switch": {
branches:[ {
case: {
"$lte":[ "$esDeliveryTickets.ticketdate", null]
},
then: "Invoiced"
}, {
case: {
"$lte":[ "$esBlendTickets.ticketdate", null]
},
then: "Invoiced"
}],
default: "Invoiced-Only"
}
}