mongodbmongodb-queryaggregation-frameworkmongodb-java-3.3.0

Setdifference giving incorrect results


We are trying to print the difference of 2 arrays,retrieved from different collections as below.However,the setdifference does not seem to work .
What may be wrong?
Expected output:

{ "request" : [{ "requestId" : "REQ4" }], "unsent" : ["1234"] }

Code excerpt and stage output as below :

AggregateIterable<Document> diff = 
                    scrips.aggregate(Arrays.asList(
                        Aggregates.group(null, Accumulators.addToSet("global", "$scrip"))
                    ,Aggregates.lookup("requests",new ArrayList<Bson>(Arrays.asList(new Document(
                            Document.parse("{\"$match\": { \"requestId\":'" + reqparam + "'}}")))),"request")

[output here: { "_id" : null, "global" : ["3553", "5647", "0001"], "request" : [{ "_id" : { "$oid" : "5d6e37db1886a24e70b88b42" }, "requestId" : "REQ4", "scrips" : ["3553", "5647", "1234"] }] }]

        ,Aggregates.project(
                    Projections.fields(
                    Projections.excludeId(),
                    Projections.computed("unsent", 
                            Document.parse("{ $setDifference: [\"$request.scrips\", \"$global\"] }"))
                )
            )

[output here: { "request" : [{ "requestId" : "REQ4" }], "unsent" : [["3553", "5647", "1234"]] }]


Solution

  • Issue here is you are trying to access field in array while using setDifference that's not being accessed and just returning global scrips as it is, try adding arrayelemat inside setdifference

     {
        $project: {
          unsent: {
            $setDifference: [
              {
                $arrayElemAt: [
                  "$request.scrips",
                  0
                ]
              },
              "$global"
            ]
          }
        }
      }
    

    giving output:

    [
      {
        "_id": null,
        "scrips": [
          "1234"
        ]
      }
    ]