Mongodb data types: Filtering Array vs Object vs Array of Object

I am querying for documents where a specific field in each document, say “offices” for example, can be of type object or array. The problem is that when I am querying for documents with “offices” field of type object I am getting documents with “offices” array type. Here is my query;

db.companies.find(  {  offices:  {  $type: 3  }  } )

Are array type fields referred as object types as well? Or is it some other problem?

According to documentation arrays are $type:4.

c.find()
{ _id: ObjectId("63d2849e4ab82600010427db"), offices: [] }
{ _id: ObjectId("63d284b84ab82600010427dc"),
  offices: { city: 'Montreal' } }
c.find( {  offices:  {  $type: 3  }  })
{ _id: ObjectId("63d284b84ab82600010427dc"),
  offices: { city: 'Montreal' } }

Please provide sample documents that do not behave according to documentation.

I am sure you have something else because your query works well. check this Mongo playground (use type 4 for array)

Sorry, I forgot to note that the field I am querying by can be an object or an array of objects. I have tried my own case in the playground. I think that because the field contains objects when its of type array, the query still returning those documents.
Examples of documents:

{
    "company": "B",
    "offices": [
      {
        city: "Tashkent"
      }
    ]
  },
  {
    "company": "C",
    "offices": {
      "location": "somewhere"
    }
  }

Alright, I see what you mean and I am also surprised to see this result. This may have something to do with the unwind operator, but logically that should not be happening in filtering.

Here is the updated dataset on playground:
Playground - Array of Objects are filtered on both type 3 and 4

@steevej, I am of no use now. do you have an idea and/or link for this? or can you tag other members that may help?

Sorry, I read about the $type operator but forgot on case:

  • If we apply $type for array fields then we get documents where that array field contains at least one element which matches the type
    To see more for answer

Thank you very much for your support

Thanks for the question, the complete example and the answer’s link. I forgot the same case.

Saru mo ki kara ochiru

If the goal is to filter of the type of the field offices rather than the element of offices when offices is an array. That is to only get company:A and company:C in the playground example. The aggregation version of $type can be use:

c.find( { $expr : { $eq : [ { $type : "$offices"} , "object" ] } } )
2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.