Search code examples
mongodbdelphimongo-c-driver

Get a document with a specific _id with mongo-delphi-driver


I have to perform a query on mongodb, i would like select only a document has a particular _id (type ObjectId).
I use "Strict mode" sintax and in particular the operator $oid for compare _id with a string.
But it doesn't work!, I don't now if it is a bug (a bag of mongo-c-driver/mongo-delphi-driver) or if I write wrong code for make a query on ObjectId field.

Below a simple snippet of code, the document with that _id exists but the bson document is nil

  var 
    b : TBson;
  begin
    b := mongo.findOne(ns,(BSON(['_id','{','$oid','58c6b6af9b2dcd04ae46844d','}'])));
    if b = nil then
      ShowMessage('No match')
    else
      ShowRecord(b);
  end

https://docs.mongodb.com/manual/reference/mongodb-extended-json/

I also try with this two methods...

var
  bb : TBsonBuffer;
  query, b : TBson;
  cursor : TMongoCursor;
begin
  bb := TbsonBuffer.Create();
  bb.startObject('_id');
  bb.append('$oid', PAnsiChar('"58c6b6af9b2dcd04ae46844d"'));
  bb.finishObject();

  query := bb.finish();
  b := mongo.findOne(ns, query);
  if b = nil then
    ShowMessage('No match')
  else
    ShowRecord(b);
end

and

var
  bb : TBsonBuffer;
  query, b : TBson;
  id : TBsonOID;
begin
  id := TBsonOID.Create('58c6b6af9b2dcd04ae46844d');
  bb := TbsonBuffer.Create();
  bb.startObject('_id');
  bb.append('$oid', id);
  bb.finishObject();

  query := bb.finish();
  b := mongo.findOne(ns, query);
  if b = nil then
    ShowMessage('No match')
  else
    ShowRecord(b);
end;

Solution

  • As it says here, the strict mode JSON interface is only for use with the HTTP API and command line tools. Drivers are expected to use proper BSON. I think you can do this in Delphi like this:

    b := mongo.findOne(ns(BSON(['_id',TBsonOID.Create('58c6b6af9b2dcd04ae46844d')])));
    

    but I'm not really a delphi guy.

    edit: the TBsonOID example you added should be like this I think:

    var
      bb : TBsonBuffer;
      query, b : TBson;
      id : TBsonOID;
    begin
      id := TBsonOID.Create('58c6b6af9b2dcd04ae46844d');
      bb := TbsonBuffer.Create();
      // _id isnt a json object it is an oid.
      bb.append('_id', id);
      query := bb.finish();
      b := mongo.findOne(ns, query);
      if b = nil then
        ShowMessage('No match')
      else
        ShowRecord(b);
    end;