#1 2015-03-21 18:23:40

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

MongoDB Collection REMOVE: I'm puzzled...

Here's what puzzles me. I use RoboMongo (or MongoVue) to connect to my MongoDB server, and manually type this query:

db.smblacklist.remove({"TimeStamp":{$lte:new ISODate("2015-03-21T18:10:27.000Z")}, "Persistence":"Temporary"})

And the above query works like a charm. All documents with a timestamp less than the isodate I specify (and with Persistence=Temporary) are deleted.
Good! Then I would expect the following Delphi code to work just the same:

ruQ := '{"TimeStamp":{$lte:new ISODate("2015-03-21T18:10:27.000Z")}, "Persistence":"Temporary"}';
fBListColl.Remove(ruQ);

But it doesn't. The query is executed without errors or exceptions... but NOTHING gets deleted from the database.
I really am puzzled. What am I doing wrong?

Offline

#2 2015-03-21 19:35:02

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

Re: MongoDB Collection REMOVE: I'm puzzled...

Thé ISO date format is not the same.

See the doc about our extended json support.

Offline

#3 2015-03-21 20:35:06

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: MongoDB Collection REMOVE: I'm puzzled...

So... the first query works because RoboMongo sends it to MongoDB in "shell mode", and instead fBListColl.Remove expects a query written in "strict mode"?
Is that what you mean? I'll give it a try...

Offline

#4 2015-03-21 21:01:12

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: MongoDB Collection REMOVE: I'm puzzled...

Mmmm, nope... built the query using "strict mode" JSON notation, as per the MongoDB extended JSON official document. And it still doesn't work.
Since the "offset" is not clarified by the MongoDB extended JSON notation document, I tried several variations of it. None of them works.

ruQ := '{"TimeStamp":{"$lte":{"$date":"2015-03-21T20:19:36.000Z"}}}';
fPreBListColl.Remove(ruQ);

ruQ := '{"TimeStamp":{"$lte":{"$date":"2015-03-21T20:19:36.000+0"}}}';
fPreBListColl.Remove(ruQ);

ruQ := '{"TimeStamp":{"$lte":{"$date":"2015-03-21T20:19:36.000+0000"}}}';
fPreBListColl.Remove(ruQ);

Offline

#5 2015-03-22 08:55:55

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

Re: MongoDB Collection REMOVE: I'm puzzled...

First of all, our internal JSON format may be:

ruQ := '{"TimeStamp":{"$lte":{"$date":"2015-03-21T20:19:36"}}}';

Since our ISO-8601 flavor stops at the second, and expects UTC time zone (as it should in a DB storage).

But take a look at the Remove() methods documentation.

    /// delete an existing document or several documents in a collection
    // - Query parameter should be TDocVariant (i.e. created via _JsonFast() or
    // _JsonFastFmt()) or TBSONVariant (created via BSONVariant())
    // - Query is the selection criteria for the deletion; use the same query
    // selectors as used in the Find() method
    // - to limit the deletion to just one document, set Flags to [mdfSingleRemove] 
    // - to delete all documents matching the deletion criteria, leave it to []
    procedure Remove(const Query: variant; Flags: TMongoDeleteFlags=[]); overload;
    /// delete an existing document in a collection, by its _id field
    // - _id will identify the unique document to be deleted
    procedure RemoveOne(const _id: TBSONObjectID); overload;
    /// delete an existing document in a collection, by its _id field
    // - _id will identify the unique document to be deleted
    procedure RemoveOne(const _id: variant); overload;
    /// delete an existing document or several documents in a collection
    // - Query parameter can be specified as JSON objects with parameters
    // - Query is the selection criteria for the deletion; use the same query
    // selectors as used in the Find() method
    // - to limit the deletion to just one document, set Flags to [mdfSingleRemove] 
    // - to delete all documents matching the deletion criteria, leave it to []
    procedure RemoveFmt(Query: PUTF8Char; const QueryParams: array of const;
       Flags: TMongoDeleteFlags=[]); 

So your code is executing

Remove(const Query: variant...

with a string as Query parameter: in this case, the method is expected a CSV projection... which does not make sense here for deletion!

So you may try

ruQ := '{"TimeStamp":{"$lte":{"$date":"2015-03-21T20:19:36.000Z"}}}';
fPreBListColl.Remove(BSONVariant(ruQ));

For more efficient coding, consider using directly a parametered TBSONVariant, so the RemoveFmt() method:

fPreBListColl.RemoveFmt('{"TimeStamp":{"$lte":{"$date":?}}}',[],[aDateTimeVariable]);

Offline

#6 2015-03-22 15:05:57

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: MongoDB Collection REMOVE: I'm puzzled...

Interestingly enough...

This one works:

ruQ := '{"TimeStamp":{"$lte":{"$date":"2015-03-21T20:19:36"}}}';
fPreBListColl.Remove(BSONVariant(ruQ));

But this one does not work:

fPreBListColl.RemoveFmt('{"TimeStamp":{"$lte":{"$date":?}}}',[aDateTimeVariable],[]);

Offline

#7 2015-03-22 19:00:17

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

Re: MongoDB Collection REMOVE: I'm puzzled...

The first [] is for % parameters, and the second [] for ? parameters!
See FormatUTF8() syntax.

You should write:

fPreBListColl.RemoveFmt('{"TimeStamp":{"$lte":{"$date":?}}}',[],[aDateTimeVariable]);

(as I wrote above)

Offline

#8 2015-03-24 04:30:07

BBackSoon
Member
Registered: 2014-11-15
Posts: 41

Re: MongoDB Collection REMOVE: I'm puzzled...

If I invert the parameters and use them the way you wrote, it doesn't compile.
That's why I inverted them.
The compiler says: there is no overloaded version of that function that can be called with these parameters
(maybe I have to update to the latest mORMot nightly build? I downloaded the latest only few days ago...)

Offline

Board footer

Powered by FluxBB