0

Hi everyone I have a collection of documents like bellow. I want to directly get "rights" from roles array for params: _id, groups._id, roles._id using java mongo driver.

{
  "_id": 1000002,
  "groups": [
    {
      "_id": 1,
      "roles": [
        {
          "rights": 3,
          "_id": 1
        },
        {
          "rights": 7,
          "_id": 2
        },
        {
          "rights": 3,
          "_id": 3
        }
      ]
    }
  ],
  "timestamp": {
    "$date": {
      "$numberLong": "1675267318028"
    }
  },
  "users": [
    {
      "accessProviderId": 1,
      "rights": 1,
      "_id": 4
    },
    {
      "accessProviderId": 1,
      "rights": 3,
      "_id": 5
    }
  ]
}

I have AccessListItem class which represents this document and I have used Bson filters to get it from mongo, but after fetching i had to get information through java function.. I want to get int value directly from mongo base.

        Bson fileFilter = Filters.eq("_id", itemId);
        Bson groupFilter = Filters.elemMatch("groups", Document.parse("{_id:"+groupId+"}"));
        Bson roleFilter = Filters.elemMatch("groups.roles", Document.parse("{_id:"+role+"}"));

        Bson finalFilter = Filters.and(fileFilter, Filters.and(groupFilter,roleFilter));

        MongoCollection<AccessListItem> accessListItemMongoCollection =      MongoUtils.getAccessCollection(type);
        AccessListItem accessListItem =  accessListItemMongoCollection.find(finalFilter).first();

1 Answer 1

1

The short answer is you can't.

MongoDB is designed for returning documents, that is, objects containing key-value pairs. There is no mechanism for a MongoDB query to return just a value, i.e. it will never return just 3 or [3].

You could use aggregation with a $project stage at the end to give you a simplified object like:

{ rights: 3}

In javascript that might look like:

db.collection.aggregate([
  {$match: {
      _id: itemId,
      "groups._id": groupId,
      "groups.roles._id": role
  }},
  {$project: {
      _id: 0,
      group: {
        $first: {
          $filter: {
            input: "$groups",
            cond: {$eq: ["$$this._id",groupId]}
          }
        }
      }
  }},
  {$project: {
      "roles": {
        $first: {
          $filter: {
            input: "$group.roles",
            cond: { $eq: [ "$$this._id",role]}
          }
        }
      }
  }},
  {$project: {
      rights: "$roles.rights"
  }}
])

Example: Playground

I'm not familiar with spring boot, so I'm not sure what that would look like in Java.

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

1 Comment

Thank you, you got the point. I want something like this in Java if someone knows.

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.