Mongodb 总计$ne未按预期工作

Mongodb 总计$ne未按预期工作,mongodb,null,Mongodb,Null,我正在尝试下面的聚合,但是使用$ne和null似乎没有得到预期的结果 我尝试过其他解决方案,比如使用$cond、$not和$eq的组合,但都没有效果。使用$gt:[“$unloadeddate”,null]似乎会给出一些结果,但这似乎不是正确的语法,我担心在整个数据集上正确运行是不可靠的 另外,查询如下: db.getCollection('esInvoices').find({"esBlendTickets.loadeddate":{$ne:null}}) 。。。返回结果,因此不确定聚合函数

我正在尝试下面的聚合,但是使用$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"
    }
}
。。。但这第二部分(除了结果值外,基本上是相同的逻辑)没有按预期工作…

"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"
            }
        }
    }}])

我想我遇到了和你一样的问题。目前正在使用Mongo3.4。据我所知,将查询
$ne
与聚合
$ne
进行比较时,查询的行为与聚合
$ne
不同。把我甩了一会儿

具体地说,当
$field
未定义时,管道中的
{$ne:['$field',null]}
谓词将返回
true

但是,当使用(而不是
$aggregate
)时,
{field:{$ne:null}
谓词将在
$field
未定义时返回这些文档的
false

我的解决方法是将
$project
{field:{$ifNull:[''$field':null]}一起使用
在前面的步骤中,将该字段的
未定义的
实例转换为显式的
null
s,这将使聚合的
$ne
按我的需要工作。无论出于何种原因,都可以使用null、未定义和缺少的字段。不确定为什么
$ne
不同


这里有一个复制的例子

db.test.insertMany([
    { a: 1, b: 'string' },
    { a: 2, b: null },
    { a: 3 },
])

db.test.find({ b: { $ne: null }}, { _id: 0 })
/*
returns:
{
    "a" : 1.0,
    "b" : "string"
}
*/

db.test.aggregate([
    { $project: {
        _id: 0,
        a: 1,
        b: 1,
        switched: { $switch: {
            branches: [
                { case: { $ne: [ '$b', null ] }, then: 'cased' },
            ],
            default: 'default',  
        }}

    }}
])
/*
returns:
{
    "a" : 1.0,
    "b" : "string",
    "switched" : "cased"
},
{
    "a" : 2.0,
    "b" : null,
    "switched" : "default"
},
{
    "a" : 3.0,
    "switched" : "cased" <--
}
*/
db.test.insertMany([
{a:1,b:'string'},
{a:2,b:null},
{a:3},
])
find({b:{$ne:null},{u id:0})
/*
返回:
{
“a”:1.0,
“b”:“字符串”
}
*/
db.test.aggregate([
{$项目:{
_id:0,
答:1,,
b:1,
已切换:{$switch:{
分支机构:[
{case:{$ne:['$b',null]},然后:'cased'},
],
默认值:“默认值”,
}}
}}
])
/*
返回:
{
“a”:1.0,
“b”:“字符串”,
“已切换”:“已装箱”
},
{
“a”:2.0,
“b”:空,
“切换”:“默认值”
},
{
“a”:3.0,

“切换”:“cased”我想我遇到了与您相同的问题。目前使用Mongo 3.4。从我可以看出,当您将查询与
null
进行比较时,查询
$ne
的行为与聚合
$ne
的行为不同。这让我有点失望

具体地说,当
$field
未定义时,管道中的
{$ne:['$field',null]}
谓词将返回
true

但是,当使用(而不是
$aggregate
)时,
{field:{$ne:null}
谓词将在
$field
未定义时返回这些文档的
false

我的解决方法是将
$project
{field:{$ifNull:[''$field':null]}一起使用
在前面的步骤中,将该字段的
未定义的
实例转换为显式的
null
s,这将使聚合的
$ne
按我的需要工作。无论出于何种原因,都可以使用null、未定义和缺少的字段。不确定为什么
$ne
不同


这里有一个复制的例子

db.test.insertMany([
    { a: 1, b: 'string' },
    { a: 2, b: null },
    { a: 3 },
])

db.test.find({ b: { $ne: null }}, { _id: 0 })
/*
returns:
{
    "a" : 1.0,
    "b" : "string"
}
*/

db.test.aggregate([
    { $project: {
        _id: 0,
        a: 1,
        b: 1,
        switched: { $switch: {
            branches: [
                { case: { $ne: [ '$b', null ] }, then: 'cased' },
            ],
            default: 'default',  
        }}

    }}
])
/*
returns:
{
    "a" : 1.0,
    "b" : "string",
    "switched" : "cased"
},
{
    "a" : 2.0,
    "b" : null,
    "switched" : "default"
},
{
    "a" : 3.0,
    "switched" : "cased" <--
}
*/
db.test.insertMany([
{a:1,b:'string'},
{a:2,b:null},
{a:3},
])
find({b:{$ne:null},{u id:0})
/*
返回:
{
“a”:1.0,
“b”:“字符串”
}
*/
db.test.aggregate([
{$项目:{
_id:0,
答:1,,
b:1,
已切换:{$switch:{
分支机构:[
{case:{$ne:['$b',null]},然后:'cased'},
],
默认值:“默认值”,
}}
}}
])
/*
返回:
{
“a”:1.0,
“b”:“字符串”,
“已切换”:“已装箱”
},
{
“a”:2.0,
“b”:空,
“切换”:“默认值”
},
{
“a”:3.0,

“switched”:“cased”问题是缺少的字段是
未定义的
,而
null
字段是空的。编写
时,“$ne”:[“$esDeliveryTickets.ticketdate”,null]
不过滤前者,只过滤后者

但是
undefined
null
小。为了过滤它们,只需将
lte
/
gt
改为
eq
/
ne
。因此此查询返回所有现有值:

见示例:

db.test.insertOne(
{
“a”:10,
“b”:空
})
...
db.getCollection('mytest').find({},
{
“a”:{$lte:[“$a”,null]},
“b”:{$lte:[“$b”,null]},
“c”:{$lte:[“$c”,null]},
})
// {
//“_id”:ObjectId(“606724f38ec4d26b981b5a1c”),
//“a”:错,
//“b”:是的,
//“c”:正确
// }
就你而言:

"stagename": { "$switch": {
        branches:[ {
            case: {
                "$gt":[ "$esDeliveryTickets.ticketdate", null]
            },
            then: "Invoiced"
        }, {
            case: {
                "$gt":[ "$esBlendTickets.ticketdate", null]
            },
            then: "Invoiced"
        }],
        default: "Invoiced-Only"
    }
}
这个函数只返回缺少的(或空)值:


问题是缺少的字段是
未定义的
,而
null
字段是空的。当您编写
时,“$ne”:[“$esDeliveryTickets.ticketdate”,null]
您不过滤前者,而只过滤后者

但是
undefined
null
小。为了过滤它们,只需将
lte
/
gt
改为
eq
/
ne
。因此此查询返回所有现有值:

见示例:

db.test.insertOne(
{
“a”:10,
“b”:空
})
...
db.getCollection('mytest').find({},
{
“a”:{$lte:[“$a”,null]},
“b”:{$lte:[“$b”,null]},
“c”