假设MongoDB有一个带有“sample1”对象的集合,该对象包含以下字段:
/* 1 */ {
"_id" : 123456,
"name" : "question",
"day" : "2018-03-21",
"field1" : 10,
"field2" : NaN,
"field3" : NaN,
"field4" : NaN,
"field5" : NaN }
/* 2 */ {
"_id" : 7896321,
"name" : "question",
"day" : "2018-03-22",
"field1" : NaN,
"field2" : NaN,
"field3" : NaN,
"field4" : NaN,
"field5" : 20 }
我想要的是一个字段“列表”,它只显示那些没有NaN作为值的字段。 查询可能看起来像
db.getCollection('sample1').find({"*" : $ne{NaN}})
[注意:我找到的所有答案都指定了fieldname(s)= Key。唉,我需要一个通配符而不是名称]
上述demo_query的结果类似于
Result:
/* 1 */
{
"_id" : 123456,
"name" : "question",
"day" : "2018-03-21",
"field1" : 10
}
/* 2 */
{
"_id" : 7896321,
"name" : "question",
"day" : "2018-03-22",
"field5" : 20
}
随后提出了一个跟进问题: 是否有可能修改上述查询,即获得 (A)一个具有NaN或NaN值的字段列表 (B)没有NaN的一个字段列表?
Result (A): List of fields that have at least in one object a given field might have NaN
{"field1"
"field2"
"field3"
"field4"
"field5" }
Result (B): List of fields that never (= in no object of a given collection) have the value NaN
{"_id"
"name"
"day" }
我在JS方面的经验非常有限。可能这可以使用PyMongo完成吗?
万分感谢任何建议!
答案 0 :(得分:1)
利用聚合框架中提供的 $objectToArray
运算符来转换顶级文档(通过系统变量 $$ROOT
)成为键值对的数组,即保存字段名称的键,值保存字段值。这可以通过表达式
{ "$objectToArray": "$$ROOT" }
将返回,例如带有_id的第一个文档:123456
[
{
"k" : "_id",
"v" : 123456
},
{
"k" : "name",
"v" : "question"
},
{
"k" : "day",
"v" : "2018-03-21"
},
{
"k" : "field1",
"v" : 10
},
{
"k" : "field2",
"v" : NaN
},
{
"k" : "field3",
"v" : NaN
},
{
"k" : "field4",
"v" : NaN
},
{
"k" : "field5",
"v" : NaN
}
]
获取此数组后,您可以使用 $filter
和 $map
进行一些过滤,然后获取所需的列表。
以下聚合操作
db.getCollection('sample1').aggregate([
{ "$addFields": {
"NaNFields": {
"$map": {
"input": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": { "$eq": [ "$$el.v", NaN ] }
}
},
"as": "field",
"in": "$$field.k"
}
},
"NonNaNFields": {
"$map": {
"input": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": { "$ne": [ "$$el.v", NaN ] }
}
},
"as": "field",
"in": "$$field.k"
}
}
} }
])
产量
/* 1 */
{
"_id" : 123456,
"name" : "question",
"day" : "2018-03-21",
"field1" : 10,
"field2" : NaN,
"field3" : NaN,
"field4" : NaN,
"field5" : NaN,
"NaNFields" : [
"field2",
"field3",
"field4",
"field5"
],
"NonNaNFields" : [
"_id",
"name",
"day",
"field1"
]
}
/* 2 */
{
"_id" : 7896321,
"name" : "question",
"day" : "2018-03-22",
"field1" : NaN,
"field2" : NaN,
"field3" : NaN,
"field4" : NaN,
"field5" : 20,
"NaNFields" : [
"field1",
"field2",
"field3",
"field4"
],
"NonNaNFields" : [
"_id",
"name",
"day",
"field5"
]
}