I am trying to figure why some array fields are returning type object
when utilizing aggregate.
Assume a collection baa
, whose field foo
can have any of the following values []
, [{...}]
, [{...},{...}]
or {...}
.
If I run the following query:
db.baa.aggregate([{$match: { foo : {$type: "object"}} },
{$project: { foo : { $type: "$foo" }}}
]);
I get the following:
[{_id: xxx, foo: array}, ....]
This query would be later used to update all entries, whose foo
fields is of type object
.
Am I missing something in here?
Thanks in advance
CodePudding user response:
From the docs
For documents where field is an array, $type returns documents in which at least one array element matches a type passed to $type.
So the query {foo: {$type: "object"}}
will match the document { foo: [{}]}
because the array contains an object.
You might try matching objects and explicitly excluding arrays:
{foo: {$type: "object", $not: {$type: "array" }}}}
CodePudding user response:
We have 2 $type
operators
- query operator, that matches if some type or its an array that contains at least 1 member with that type
For example
{} ,[{}]
both match with "object" This returns true or false. - aggregate operator that is strict and returns the exact type. For example {"$type" : "$foo"} will return "object" (a string with the type)
Your query has the problem that you use the query operator to do a strict type match.And also you are using the query operator in project, and you cant do that, in project you need the $type
aggregate operator.
If you know that if its not array it will be object, you can use this.
aggregate(
[ {
"$match" : {
"foo" : {
"$not" : {
"$type" : "array"
}
}
}
} ]
)
We also have $type
aggregate operator, that is more strict and will only match objects. (not also arrays that contain at least 1 object like the $type
query operator)
aggregate(
[ {
"$match" : {
"$expr" : {
"$eq" : [ {
"$type" : "$foo"
}, "object" ]
}
}
} ]
)
With project i dont know what you want to do, but you cant use the query operator there. Only the aggregate operator.