2

I am attempting to write a code that finds objects in MongoDB collection with Linq. Here's my code:

 class Program
{
    static void Main(string[] args)
    {
        var client = new MongoClient();
        var db = client.GetDatabase("SoundsDB");
        var collection = db.GetCollection<Sound>("SoundsCollection");
        string myID = "0vvyXSoSHI";

        var myObjects = collection
            .Find(b => b.objectId == myID);

    }
}

public class Sound
{
    public string _id { get; set; }
    public Result[] results { get; set; }
}

public class Result
{
    public Audio_File audio_file { get; set; }
    public DateTime createdAt { get; set; }
    public string location { get; set; }
    public string objectId { get; set; }
    public DateTime updatedAt { get; set; }
}

public class Audio_File
{
    public string __type { get; set; }
    public string name { get; set; }
    public string url { get; set; }
}

Here's the JSON in my MongoDB collection:

{
"_id" : ObjectId("56acced71b8ac8702446e8c6"),
"results" : [ 
    {
        "audio_file" : {
            "__type" : "File",
            "name" : "tfss-3c489351-0338-4903-8d94-a0f0c7091ef9-hi.m4a",
            "url" : "http://files.parsetfss.com/hithere.m4a"
        },
        "createdAt" : "2014-12-27T22:59:04.349Z",
        "location" : "Home",
        "objectId" : "0vvyXSoSHI",
        "updatedAt" : "2015-02-26T22:48:02.264Z"
    }
        ]

}

I am trying to make it work but in the following line:

                .Find(b => b.objectId == myID)

I get this error: Cannot convert lambda expression to type 'MongoDB.Driver.FilterDefinition' because it is not a delegate type

Any idea how can I fix it and be able to search through the JSON for objects using their objectId? Thanks!

Pavel Zagalsky
  • 1,620
  • 7
  • 22
  • 52

1 Answers1

2

I think the problem is that you are searching for a sub-document, not the main doc. Try this:

var myObjects = collection
    .Find(b => b.results.Any(r=>r.objectId == myID));

Also - make sure that the objectId value is actually a string in your collection. It seems like it's a string in the object model but an objectId in the db. You may need to (a) change your object model and (b) change that query so that you are asking for r.objectId == ObjectId.Parse(myID) instead of the way I wrote it.

c# MongoDb .Find is Async

If you're using the c# drivers, you probably also need to implement async for this call:

static void Main() {
   MainAsync().Wait();
}

static async Task MainAsync() {

    var client = new MongoClient();
    var db = client.GetDatabase("SoundsDB");
    var collection = db.GetCollection<Sound>("SoundsCollection");
    string myID = "0vvyXSoSHI";

    var myObjects = await collection
        .Find(b => b.objectId == myID).ToListAsync();

}

This way, you are using find, and converting the results to a list (so, myObjects will be a List<SoundsCollection> object).

bri
  • 2,932
  • 16
  • 17
  • Hmm, just checked it and it's a string in the DB.. I ran the code you wrote and I think it runs successfully but I am not sure since I cannot see any data inside this object – Pavel Zagalsky Jan 30 '16 at 22:37
  • If you're using the latest mongodb driver(s), then it's all async. See updates to the answer. – bri Jan 30 '16 at 22:40
  • Not sure I understood you.. How do I do it async way? – Pavel Zagalsky Jan 30 '16 at 22:44
  • Take a look... I just added an async wrapper around your Main() method so that you can use the built in task/await functionality in the c# driver. – bri Jan 30 '16 at 22:50
  • Alright, now I am getting another error: Message=An error occurred while deserializing the _id property of class TOKPOC.Program+TOK: Cannot deserialize a 'String' from BsonType 'ObjectId'. What do you think? – Pavel Zagalsky Jan 30 '16 at 23:05
  • 1
    I think that's another question ;-)... but I'll give you this one for free. Change the type of Sound._id to ObjectId. AND - [take a look a this post](http://stackoverflow.com/questions/6063219/how-to-manage-id-field-when-using-poco-with-mongodb-c-sharp-driver) for more info. – bri Jan 30 '16 at 23:08
  • Thanks! I'll have a look tomorrow morning! Many thanks – Pavel Zagalsky Jan 30 '16 at 23:17