4d-databaseorda

ORDA: How do I specify field order when using entitySelection.toCollection()?


Background

I'm converting old 4D Database code to use new ORDA concepts introduced in v17. However, I've noticed an oddity. When I have an entitySelection that I created using ds[$vtTableName].query(), and I convert that entitySelection to a collection (using .toCollection(), the order of the fields that I specify isn't honored.

Example Code:

C_OBJECT($voSelection)
$voSelection:=ds.Users.query("Active = 'True'")

C_COLLECTION($vcUsers)
$vcUsers:=$voSelection.toCollection("FirstName, LastName, DTLastSignin")

Expected Output

I would expect $vcUsers to be a collection of objects, and that each object would look like:

{ "FirstName" : "John", "LastName" : "Smith", "DTLastSignin" : "2019-10-12T32:23:00" }

Actual Output

Instead, I'm getting a different order:

{ "DTLastSignin" : "2019-10-12T32:23:00", "FirstName" : "John", "LastName" : "Smith" }

This has broken some of my API consumers because they expect to be able to specify field order, which the old way (Selection to JSON) respects. However, toCollection() doesn't appear to.

I can't find any sort of documentation about field order and if it is even suppose to. The official documentation shows the fields respecting the order, but maybe it's just a coincidence.


Solution

  • The answer to this is that you can't, because the toCollection() field list is just a filter. Under the hood, the Entity's properties are being looped through in their natural order, and being filtered whether or not the field is one of the specified filter fields.

    That is the reason that .toCollection is faster than the clasic Selection to JSON method.

    One way around this potentially would be to use use a .map() function. However, that would degrade performance, probably. I haven't done any profiling, so I'm not sure.