10

Let's suppose I have the following document structure in MongoDB.

{
    _id: ####,
    Ancestors: [
        { _id: 1, Name: "asdf" },
        { _id: 2, Name: "jkl;" },
        ...
    ]
}

I want to find every document that contains an Ancestor where _id of the Ancestor is 2.

I can run this query in the mongo shell using this: db.projects.find({"Ancestors._id": 2})

I can also run this query using the official C# driver using this: Query.EQ("Ancestors._id", new BsonInt32(rootProjectId)).

Here are my POCOs; the actual classes I'm using have more properties than this, but I didn't want to clutter up the question with unnecessary details:

public class Project
{
    public int Id { get; set; }
    public List<ProjectRef> Ancestors { get; set; }
}

public class ProjectRef
{
    public int Id { get; set; }
    public string Name { get; set; }
}

My question is: How can I write a strongly-typed query using the C# driver so that I don't have to pass in "Ancestors._id" as a string? I want to be able to do something like Query<Project>.EQ(p => p.Id, rootProjectId) so that I can instead use a member expression and let the class mappings tell the driver that it should use "Ancestors._id".

1

1 Answer 1

14

ElemMatch is your friend in this case.

try the following:

var ancestorsQuery = Query<ProjectRef>.EQ(pr => pr.Id, rootProjectId);
var finalQuery = Query<Project>.ElemMatch(p => p.Ancestors, builder => ancestorsQuery));

use finalQuery within a Find command on the Projects collection.

Sign up to request clarification or add additional context in comments.

2 Comments

The query builder supplied to the second parameter of Query<>.ElemMatch() is typed by the first parameter, so if you want to write the whole query as a single statement, you can do: var finalQuery = Query<Project>.ElemMatch(p => p.Ancestors, builder => builder.EQ(pr => pr.Id, rootProjectId)); and save a couple keystrokes.
any idea why would positional operator wont work by using this way?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.