Search code examples
c#mongodbmongodb-.net-driver

MongoDb c# bad unknown operator exception


I execute the following query :

{
    $query : { 
        "userId" : 11851, "p2l.listId" : 38882, "isDeleted" : false 
    },       
    $orderby: { email: 1},  
    $skip: 0, 
    $limit:100 
}

via the following code :

BsonDocument document = BsonSerializer.Deserialize<BsonDocument>(queryString);
QueryDocument queryDoc = new QueryDocument(document);
var toReturn = collection.Find(queryDoc);
return toReturn.ToList();

and I get the following exception:

[MongoDB.Driver.MongoQueryException] = {"QueryFailure flag was true (response was { \"$err\" : \"Can't canonicalize query: BadValue unknown top level operator: $query\", \"code\" : 17287 })."}

I use MongoDb 3.0 and C# driver 2.0.

Is there any other way to execute that query ? I need keep it in string format in sql database, so i need serialize/deserialize it.


Solution

  • That isn't a valid query. While you can add $orderby that way (but it's not recommended), skip and limit are not part of the document. Best thing to do is to not try to build it that way and instead let the driver build it for you. This will also make your application future proof for when the server changes how queries are issued (https://jira.mongodb.org/browse/SERVER-15176).

    BsonDocument document = BsonDocument.Parse(queryString);
    QueryDocument queryDoc = new QueryDocument((BsonDocument)document["$query"]);
    
    return collection.Find(queryDoc)
        .SetSkip((int)document["$skip"])
        .SetLimit((int)document["$limit"))
        .SetSort(new SortDocument((BsonDocument)document["$orderby"]))
        .ToList();
    

    Obviously, if some of these are conditional, you'll need to handle that too.

    On a final note, if the queryString is actually a queryString, I think you're going to find it very problematic. It will be impossible to use indexes correctly because your "users" can do absolutely anything they want. Plus, you are requiring them to understand the MongoDB query language. It would be better to model what they are allowed to do explicitly.