Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-82430

$slice (project) and $slice (aggregation) aggregation returns different results for an array nested in an array of subdocuments

    • Type: Icon: Bug Bug
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 7.0.2
    • Component/s: None
    • Query Execution
    • ALL
    • Hide

      This can also be reproduced in the mongo-compas or via C# driver. 

      In general, you can follow my description above. Insert the shown document and execute both projections to see the difference.

      Show
      This can also be reproduced in the mongo-compas or via C# driver.  In general, you can follow my description above. Insert the shown document and execute both projections to see the difference.
    • QE 2024-01-08, QE 2024-01-22

      Dear all,

      I've the following use case: I've got a model, that includes an array of models that includes an array of models. Here is an example:

       

      {
        "_id": {
          "$oid": "6537c348acf272384df46220"
        },
        "MyBoundModelList": [
          {
            "MyInt8": 50,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              },
              {
                "MyString": "1",
                "MyInt32": 1
              },
              {
                "MyString": "2",
                "MyInt32": 2
              },
              {
                "MyString": "3",
                "MyInt32": 3
              }
            ]
          },
          {
            "MyInt8": 33,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              },
              {
                "MyString": "1",
                "MyInt32": 1
              },
              {
                "MyString": "2",
                "MyInt32": 2
              }
            ]
          },
          {
            "MyInt8": 41,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              },
              {
                "MyString": "1",
                "MyInt32": 1
              },
              {
                "MyString": "2",
                "MyInt32": 2
              }
            ]
          },
          {
            "MyInt8": 16,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              },
              {
                "MyString": "1",
                "MyInt32": 1
              },
              {
                "MyString": "2",
                "MyInt32": 2
              },
              {
                "MyString": "3",
                "MyInt32": 3
              }
            ]
          }
        ]
      } 

      My goal was to slice the inner list to return just the first element. To achiev this I initially used a "normal" projection: 

      {"MyBoundModelList.MyBoundModelList": {$slice:[0,1]}} 

      This resulted in the following entity, which, in my opinion, is correct:

      {
        "_id": {
          "$oid": "6537c348acf272384df46220"
        },
        "MyBoundModelList": [
          {
            "MyInt8": 50,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              }
            ]
          },
          {
            "MyInt8": 33,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              }
            ]
          },
          {
            "MyInt8": 41,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              }
            ]
          },
          {
            "MyInt8": 16,
            "MyBoundModelList": [
              {
                "MyString": "0",
                "MyInt32": 0
              }
            ]
          }
        ]
      }

      However, since I had some truble in combination with other include projections, I had to switch to aggregation pipelines to be able to send multiple projections that are applied after each other. Thus, I converted the "normal" projection definition into a pipeline:

      new BsonDocument("$project", 
          new BsonDocument("MyBoundModelList.MyBoundModelList", 
          new BsonDocument("$slice", 
          new BsonArray
                      {
                          "$MyBoundModelList.MyBoundModelList",
                          0,
                          1
                      })))

      After executing this pipeline I saw the first different: It just returns the named lists on the path. Well, this was not expected since the "normal" slice projection acts differently but can be handled. The real "bug", at least in my opinion, happens in the inner list. Here the result of that projection:

      {
        "_id": {
          "$oid": "6537c348acf272384df46220"
        },
        "MyBoundModelList": [
          {
            "MyBoundModelList": [
              [
                {
                  "MyString": "0",
                  "MyInt32": 0
                },
                {
                  "MyString": "1",
                  "MyInt32": 1
                },
                {
                  "MyString": "2",
                  "MyInt32": 2
                },
                {
                  "MyString": "3",
                  "MyInt32": 3
                }
              ]
            ]
          },
          {
            "MyBoundModelList": [
              [
                {
                  "MyString": "0",
                  "MyInt32": 0
                },
                {
                  "MyString": "1",
                  "MyInt32": 1
                },
                {
                  "MyString": "2",
                  "MyInt32": 2
                },
                {
                  "MyString": "3",
                  "MyInt32": 3
                }
              ]
            ]
          },
          {
            "MyBoundModelList": [
              [
                {
                  "MyString": "0",
                  "MyInt32": 0
                },
                {
                  "MyString": "1",
                  "MyInt32": 1
                },
                {
                  "MyString": "2",
                  "MyInt32": 2
                },
                {
                  "MyString": "3",
                  "MyInt32": 3
                }
              ]
            ]
          },
          {
            "MyBoundModelList": [
              [
                {
                  "MyString": "0",
                  "MyInt32": 0
                },
                {
                  "MyString": "1",
                  "MyInt32": 1
                },
                {
                  "MyString": "2",
                  "MyInt32": 2
                },
                {
                  "MyString": "3",
                  "MyInt32": 3
                }
              ]
            ]
          }
        ]
      } 

      The crucial part is the inner list. There, the projection inserted additional list-brakets instead of "slicing away" elements. The result is that the inner list has just one element, as expected, but this element is the original list with all elements. 

       

            Assignee:
            foteini.alvanaki@mongodb.com Foteini Alvanaki
            Reporter:
            thorsten.schodde@bst.group Thorsten Schodde
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: