Home > Software design >  MongoDB not recognising type Object
MongoDB not recognising type Object

Time:10-06

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.

  • Related