#1 2018-09-14 07:51:10

DigDiver
Member
Registered: 2013-04-29
Posts: 137

TMongoCollection and collation

Sometime I need to specify the collation for aggregate operation.

For example, change numericOrdering flag that determines whether to compare numeric strings as numbers or as strings.

{locale: "simple", numericOrdering: true}
function TMongoCollection.AggregateCallFromJson(const pipelineJSON: RawUTF8;
  var reply,res: variant; const collation: RawUTF8 = ''): boolean;
begin // see http://docs.mongodb.org/manual/reference/command/aggregate
  if fDatabase.Client.ServerBuildInfoNumber<2020000 then
    raise EMongoException.Create('Aggregation needs MongoDB 2.2 or later');
  if fDatabase.Client.ServerBuildInfoNumber>=3060000 then begin
    // db.runCommand({aggregate:"test",pipeline:[{$group:{_id:null,max:{$max:"$_id"}}}],cursor:{}})
    if collation <> '' then
     Database.RunCommand(BSONVariant('{aggregate:"%",pipeline:[%],cursor:{}, collation:%}',[Name,pipelineJSON, collation],[]),reply)
    else
     Database.RunCommand(BSONVariant('{aggregate:"%",pipeline:[%],cursor:{}}',[Name,pipelineJSON],[]),reply);
    // {"cursor":{"firstBatch":[{"_id":null,"max":1510}],"id":0,"ns":"db.test"},"ok":1}
    res := reply.cursor;
    if not VarIsNull(res) then
      res := res.firstBatch;
  end else begin
    // db.runCommand({aggregate:"test",pipeline:[{$group:{_id:null,max:{$max:"$_id"}}}]})
    Database.RunCommand(BSONVariant('{aggregate:"%",pipeline:[%]}',[Name,pipelineJSON],[]),reply);
    // { "result" : [ { "_id" : null, "max" : 1250 } ], "ok" : 1 }
    res := reply.result;
  end;
  result := not VarIsNull(res);
end;

The code above is working for me.

Offline

Board footer

Powered by FluxBB