#1 2020-03-11 05:26:34

sgavrilov
Member
Registered: 2019-05-24
Posts: 20

Nested objects in TSQLRecord for MongoDB

Hello,

I have been exploring functionality of the mORMot in regards to the MongoDB. And I have found that if I define a record like this:

  TEmpl = class(TPersistent)
  private
    FCode: Integer;
    FName: RawUTF8;
  published
    property Code: Integer  read FCode  write FCode;
    property Name: RawUTF8  read FName  write FName;
  end;

  TSQLMongoTest = class(TSQLRecord)
  private
    FEmpl1: TEmpl;
    FEmpl2: Variant;
  public
    constructor Create; override;
    destructor Destroy; override;
  published
    property Empl1: TEmpl  read FEmpl1;
    property Empl2: Variant  read FEmpl2  write FEmpl2;
  end;

and save it to a database:

    TAutoFree.One(R, TSQLMongoTest.Create);
    R.Empl1.Code := 23;
    R.Empl1.Name := 'Empl1';
    R.Empl2 := TDocVariant.NewObject(['Code', 23, 'Name', 'Empl2']);
    Client.Add(R, True);

then the Empl2 is stored as a real "object" part of the MongoDB document but the Empl1 - as JSON in a string field:

{"_id":{"$numberInt":"1"},"Empl1":"{\"Code\":23,\"Name\":\"Empl1\"}","Empl2":{"Code":{"$numberInt":"23"},"Name":"Empl2"}}

After that, I can find the document using Eml2.Code but obviously not the Empl1.Code:

    R := TSQLMongoTest.CreateAndFillPrepare(Client, 'Empl1.Code = ?', [23]);
    try
      while R.FillOne do
        s := R.Empl1.Name;  // Is not executed
    finally
      R.Free;
    end;

    R := TSQLMongoTest.CreateAndFillPrepare(Client, 'Empl2.Code = ?', [23]);
    try
      while R.FillOne do
        s := R.Empl2.Name;  // Executed
    finally
      R.Free;
    end;

As far as I can understand, according to the documentation there should be no difference in my case between Empl2 and Empl1.

DocVariants are great! But I would like to use a predefined structure and compile-time checks as well. Is there a way to store a TObject/TPersistent/record property of a TSQLRecord descendant as an "object" part of a MongoDB document (not as JSON in a string field)?

Thank you in advance for any hints.

Best regards,
Sergey Gavrilov

Offline

#2 2020-03-11 09:16:29

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,708
Website

Re: Nested objects in TSQLRecord for MongoDB

Searching 'Empl1.Code=?' should work in latest versions of mORMotMongoDB, IIRC.

Check https://synopse.info/files/html/Synopse … #TITLE_226 as reference.
Published records are not well supported by the compilers, so their support is preliminary.
But nested objects can be stored I guess. Check https://synopse.info/files/html/Synopse … ml#TITL_52
What we usually do is use T*ObjArray published fields: register a dynamic array of one TObject class to the serializer, then the array would be stored as a BSON list.

Online

Board footer

Powered by FluxBB