Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-2002

Questions about the $filter operator in the aggregation pipleine

    • Type: Icon: Task Task
    • Resolution: Works as Designed
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 2.4.4
    • Component/s: Operations
    • Labels:
    • Environment:
      .NET Core 1.1, Windows 10 x64

      Hello, I have a few questions regarding the mongodb C# driver, as the title says I haven't been able to figure out the $filter operator in the aggregation pipline.

      The problem I'm trying to solve using a mongo query is the following, I have a collection with entries that contain an array with objects in it as follows:

      {
          "_id" : ObjectId("some-unique-id"),
          "ref" : [ 
              {
                  "name" : "something",
                  "ref" : "Something/1234"
              },
             {
                  "name" : "something",
                  "ref" : "Something/4567"
              },
             {
                  "name" : "else",
                  "ref" : "Else/1234"
              }
          ]
      }
      

      I'm trying to project the sub array so it returns only some items, I've managed to do it using a json mongo query similar to the one described in the docs.

      I didn't manage to generate one from C# code correctly. I've tried using two methods.
      The IAggregateFluent Project() method accepts two overloads, mainly using an ProjectDefinition or an Expression<Func<TInput, TOutput>>.

      The Project definition generates a json that projects the document in a non-aggregation manner

      { "ref": 1, "_id" :0 }
      

      That's not sufficient as I need to filter the array.

      The Expression<Func<TInput, TOutput>> generates it somewhat correctly but not quite.

      This is the C# code that I pass to the Aggregate pipeline

      
      Expression<Func<MongoEntry, IEnumerable<MongoReferenceComponent>>> projection = (entry) =>
                               entry
                                   .ReferenceComponents
                                   .Where(refr => refr.Name == "something");
      
      var aggregation = source.Aggregate()
          .Match(filter)
          .Project(projection);
      
      return (await aggregation.ToCursorAsync());
      
      

      This is what it generates (raises an exception)

      "$project": {
              "$filter": {
                  "input": "$ref",
                  "as": "item",
                  "cond": {
                      "$eq": [ "$$item.name", "something" ]
                  }
              }
          }
      

      And this is how it should look like

      "$project": {
              "ref": {
                  "$filter": {
                      "input": "$ref",
                      "as": "item",
                      "cond": {
                          "$eq": [ "$$item.name", "something" ]
                      }
                  }
              }
          }
      

        1. Program.cs
          3 kB
        2. ProgramCorrectVersion.cs
          3 kB

            Assignee:
            Unassigned Unassigned
            Reporter:
            emanuelmd Emanuel M
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: