delphidelphi-xe

How to insert in MongoDB


I'm doing CRUD in MongoDB. I tried this example but I'm its not working. I'm getting access violation error then stream read error. Here is my code:

var
  fdCon : TFDConnection;
  fdMongQuery : TFDMongoQuery;
  mDoc : TMongoDocument;
begin
try

  fdCon := TFDConnection.Create(nil);
  fdMongQuery := TFDMongoQuery.Create(nil);
  try
    fdCon.Params.Clear;
    fdCon.Params.DriverID := 'Mongo';
    fdCon.Params.Add('Server=' + 'localhost');
    fdCon.Params.Add('Port=' + '27017');

    fdCon.Open;

    fdMongQuery.Close;
    fdMongQuery.FieldDefs.Clear;
    fdMongQuery.FormatOptions.StrsTrim2Len := True;
    fdMongQuery.Connection := fdCon;
    fdMongQuery.DatabaseName := 'HR';
    fdMongQuery.CollectionName := 'employee';

    mDoc :=
      TMongoDocument.Create(TMongoEnv(fdCon))
          .Add('name', 'ago')
          .Add('age', 12)
          .Add('address', 'PH')
          ;

    fdMongQuery.Collection.Insert(mDoc); // access violation > stream read error
    mDoc.Free;

  finally
    fdMongQuery.Free;
    fdCon.Free;
  end;

except
end;
end;

Where did I go wrong?


Solution

  • This construction is wrong:

    mDoc :=
      TMongoDocument.Create(TMongoEnv(fdCon))
        ...
      ;
    

    You are type-casting the TFDConnection object to TMongoEnv when creating the TMongoDocument object, but that is an illegal type-cast (if you had used the as operator for the cast, it would have raised an EInvalidCast exception at runtime). TMongoDocument expects an actual TMongoEnv object.

    You need to instead type-cast the TFDConnection.CliObj property to TMongoConnection after connecting to a MongoDB server, and then you can use the TMongoConnection.Env property to get the TMongoEnv object. This is even explained in Embarcadero's documentation:

    FireDAC.Phys.MongoDBWrapper.TMongoEnv

    Do not create an instance of TMongoEnv directly. Instead, use the one from the Env property of a MongoDB connection.

    FireDAC.Phys.MongoDBWrapper.TMongoConnection

    To obtain an instance of TMongoConnection, do not create one directly. Instead, configure a TFDConnection component to connect to your MongoDB server, ensure that it is connected, and cast its CliObj property to TMongoConnection

    So, try this instead:

    mDoc :=
      TMongoDocument.Create(TMongoConnection(fdCon.CliObj).Env)
        ...
      ;