#1 2014-05-22 07:39:03

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

[mongodb] FindONe clarification

I thought that the two lines of code are equivalent, however it seems that the first is not interpreted correctly, the call does not return.


    doc:=Coll.FindDoc('{Name:?}',['{"$regex": "test.*", $options: "i"}']); // infinite loop 

    doc:=Coll.FindDoc('{Name:{"$regex": "test.*", $options: "i"}}',[]); // ok

Offline

#2 2014-05-22 07:44:14

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

Re: [mongodb] FindONe clarification

You are confusing {Name:?}  and {Name:%}
{Name:?} means that ? will be replaced by a value - and here your value is a string, not an object.

FindDoc('{Name:?}',['{"$regex": "test.*", $options: "i"}'])

will search for

{Name:"{\"$regex\": \"test.*\", $options: \"i\"}"}

Which is not the same as

FindDoc('{Name:{"$regex": "test.*", $options: "i"}}',[])

You may write:

FindDoc('{Name:?}',[BSONVariant('{"$regex": "test.*", $options: "i"}')])

to search for an object.

But there is no benefit at all in respect to "pure JSON"

FindDoc('{Name:{"$regex": "test.*", $options: "i"}}',[])

But the fact that there is an infinite loop is not expected.
It should return no match, not loop.
Where in the code does it loop for ever?

Offline

#3 2014-05-22 07:49:23

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

Re: [mongodb] FindONe clarification

AFAIK the easiest is to use directly the MongoDB extended syntax, which is handled by our unit at BSONVariant level:

FindDoc('{Name:/test.*/i}',[]);

Sounds better, no?

Offline

#4 2014-05-22 07:52:05

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [mongodb] FindONe clarification

    doc:=Coll.FindDoc('{Name:%}',['"$regex": "test.*", $options: "i"']); 


function TBSONWriter.BSONWriteDocFromJSON(JSON: PUTF8Char; aEndOfObject: PUTF8Char;
  out Kind: TBSONElementType; DoNotTryExtendedMongoSyntax: boolean): PUTF8Char;



in this point:

 '{': begin
    Kind := betDoc;
    Start := BSONDocumentBegin;
    repeat inc(JSON) until not(JSON^ in [#1..' ']);
    repeat
      // see http://docs.mongodb.org/manual/reference/mongodb-extended-json
      Name := GetJSONPropName(JSON); // BSON/JSON accepts "" as key name
      BSONWriteFromJSON(Name,JSON,@EndOfObject,DoNotTryExtendedMongoSyntax);
      if (JSON=nil) or (EndOfObject=#0) then
        exit; // invalid content
    until EndOfObject='}';
  end;

EndOfObject is always ':'

Last edited by Sabbiolina (2014-05-22 07:55:26)

Offline

#5 2014-05-22 07:57:21

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

Re: [mongodb] FindONe clarification

Your expression is not valid JSON at all.

doc:=Coll.FindDoc('{Name:%}',['"$regex": "test.*", $options: "i"']); 

Will try to parse ('{Name:%}'

Offline

#6 2014-05-22 13:13:13

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [mongodb] FindONe clarification

You are absolutely right.

But I'm a little concerned by the queries dynamically created with parts supplied by the user.

there is some function of input validation in this fantastic library?

Offline

#7 2014-05-22 13:30:37

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [mongodb] FindONe clarification

Update. This is the string that blocks the parser:

doc:=Coll.FindDoc('{Name:?}',['{"$regex": "test.*", $options: "i"}']);

Your first

Offline

#8 2014-05-22 13:35:00

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [mongodb] FindONe clarification

after formatUTF8:

'{Name:"{""$regex"": ""test.*"", $options: ""i""}"}'

Offline

Board footer

Powered by FluxBB