Nested arrays in schema

Hi there,

I have a field which is a two dimensional array that I am trying to build into a schema. The field is a set of x,y coordinates, e.g. [[1.0,1.0],[2.0,2.0],[3.0,3.0]].

The schema I am trying to apply is

{
  "title": "locations",
  "bsonType": "object",
  "required": [
    "_id",
  ],
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "boundary": {
      "title": "points",
      "bsonType": "array",
      "uniqueItems": false,
      "items": {
        "title": "xy",
        "bsonType": "array",
        "uniqueItems": false,
        "items": {
          "bsonType": "double"
        }
      }
    }
  }
}

This validates fine, but the error I am getting from the client is ‘Client query is invalid/malformed (IDENT, QUERY)’.

Is what I am trying to do possible? Any guidance anyone can give would be really appreciated!

Thanks.

Hi, Realm DB does not support storing lists of lists unfortunately at the moment. Using that JSON Schema will actually make the collection by “sync invalid”. We are currently in the process of trying to remove this limitation and have better support for geospatial data, so stay tuned for announcements on that.

Thanks,
Tyler

Thanks Tyler,

That makes sense, appreciate the response.

Look forward to future updates!

Regards,

Alec.

Any update on this issue?

Hi, I have no immediate update to share, but we have a project currently underway that should solve this issue in a more general way. Stay tuned for more!

In the interim, here is the solution we’re deploying:

  1. remove the GeoJSON from the app services schema.
  2. create a custom resolver with the parent being the object and name it the same (so if the field is geometry, call it geometry)
  3. Have the custom resolver return { coodinates: JSON.stringify(item.coordinates) }
  4. In your client app (assuming Apollo Client) create a new ApolloLink to automatically JSON.parse the geometry nodes.
  5. Create a schema for geometryString.
  6. On mutations, take your geometry $set and change it to {geometryString: JSON.stringify(item.geometry)}
  7. Create a trigger on INSERT,UPDATE,REPLACE that watches for geometryString and have it delete that value and set {geometry: JSON.parse(item.geometryString)}
  8. Wish you weren’t using app services at all.

Hope this helps anyone still waiting on MongoDB to implement nested arrays!

It looks like you’re using GraphQL. I believe nested arrays work with App Services and GraphQL, just not (yet) with Atlas Device Sync (which is what the original question was asking about).

They have not worked for me. You can generate a schema with GeoJSON data and it will generate a broken schema (that will have no error but will be unavailable to query).

Example of a broken generated schema:

{
	"geometry": {
		"bsonType": "object",
		"properties": {
			"coordinates": {
				"type": "array",
				"items": {
					"type": "array",
					"items": {
						"type": "array"
					}
				}
			},
			"type": {
				"type": "string"
			}
		}
	}
}

If you try and fix it manually, it won’t validate.

If you change it to this it will not deploy

{
	"geometry": {
		"bsonType": "object",
		"properties": {
			"coordinates": {
				"type": "array",
				"items": {
					"type": "array",
					"items": {
						"type": "array",
						"items": {
							"bsonType": "double"
						}
					}
				}
			},
			"type": {
				"type": "string"
			}
		}
	}
}

An example of GeoJSON data

{
	"geometry": {
		"type": "Polygon",
		"coordinates": [
			[
				[-96.5699999, 33.21],
				[-96.58, 32.9799999],
				[-96.92999999999999, 32.99],
				[-96.91999999999999, 33.21],
				[-96.5699999, 33.21]
			]
		]
	}
}

Hello, i am currently running into the same issue regarding GeoJSON data. Has there been any updates since last year?

I did research a bit about this and found what could be a workaround using embedded realm objects, but i was kind of looking for a simpler solution.

PS: my client app is using Kotlin, i’m not sure if this is out of context for this thread

Hi,

We are still working on removing the nested lists limitation, but on a related note – Device Sync has support for querying on GeoJSON Points now! An engineer on the team wrote a nice blog post about it here: Introducing Sync for Geospatial Data | MongoDB.

Can find the Kotlin docs here, as well as docs on how to structure GeoJSON Points here.

1 Like

Hi Jonathan,
Thank you for the reply and suggested resources. They are proving helpful to solve a part of my use case.
However, I am in the process of creating a brand new application and am in the design process. It would be amazing to structure my database data as GeoJSON from the start and not rework the whole database structure later on. The data i am working with will include polygons, linestrings and points (already implemented as GeoPoint).
Is there a an estimated release for this feature?
Will it be in the next few months or are we talking year(s)?

Hi @Omar_Al_Rafei ,

We are planning on adding in support for nested collections within the next couple of weeks / releases. Stay tuned!

1 Like