2

I am trying to get a list of all ids from a database but I am getting a result that I don't want. I want the result to be an array. There reason why I want it to be a list is that I want to use it in another query where the condition will work with the data of those ids, maybe there is a way to do that with the result I am getting but I don't know how to do it as well. But if I can get it as an array, I will be able to solve it.

Here is how I am doing it

const ids = await Db.find({accountStatus: "active"}).distinct('_id')

result

[
  new ObjectId("6259e7cb9604555d50939cff"),
  new ObjectId("6259f9502349309b80f215be"),
  new ObjectId("625a7619a4eb4fc6fc3e1507"),
  new ObjectId("625bb731a4eb4fc6fc3e1587"),
  new ObjectId("625bf74c13a4ee9f4ae9d61d"),
  new ObjectId("625c897f363d7af93a6fdd3b"),
  new ObjectId("625d2ef668610464781a34a3")
]

desired result

[
  "6259e7cb9604555d50939cff",
  "6259f9502349309b80f215be",
  "625a7619a4eb4fc6fc3e1507",
  "625bb731a4eb4fc6fc3e1587",
  "625bf74c13a4ee9f4ae9d61d",
  "625c897f363d7af93a6fdd3b",
  "625d2ef668610464781a34a3"
]

Let me know how I can get the result in an array format.

2 Answers 2

3

If you want to have a pure MongoDB query solution you can do it like this:

Db.aggregate([{
  "$match": {
    accountStatus: "active"
  }
},
{
  $project: {
    _id: {
      $toString: "$_id"
    }
  }
}])

All ObjectIds are converted to strings. I kept out the distinct operator since Ids must be unique anyways so there is no point in adding this.

Otherwise you can just map over your result and transform the ObjectIds:

const ids = (await Db.find({accountStatus: "active"}).distinct('_id'))
  .map((id) => id.toString())
Sign up to request clarification or add additional context in comments.

5 Comments

I am accessing the data with mongoose, I don't think that code will work. thanks
@Egidius it does work. Just try it out. You can use aggregate with Mongoose the same way as with the normal MongoDB driver
I added another possible solution where you just transform all ObjectIds
S Here is the error I am getting: 1 option: unhandledPromiseRejectionWarning: MongooseError: Mongoose 5.x disallows passing a spread of operators to Model.aggregate(). Instead of Model.aggregate({ $match }, { $skip }), do Model.aggregate([{ $match }, { $skip }]) 2 option: UnhandledPromiseRejectionWarning: TypeError: Db.find(...).distinct(...).map is not a function
my fault. I edited both options to fix the errors
2

Based on the example provided, there are multiple ways of getting to your desired result. I will proceed to enunciate two of them, one using a callback function and the other one using a Promise.

Method 1

const ids = await Db.find({accountStatus: "active"}).distinct('_id', 
 function(error, ids) {
    // ids is an array of all ObjectIds
    let strArr = []; // Initialize empty array
    // Iterate through ids
    for (let id of ids){
       // Push each id into strArr
       // Id is formatted as a String by using ObjectId's str attribute 
       strArr.push(id.str);
    }
    // Return resulting array
    return strArr;
});

Method 2

// Storing the db call as a Promise
const dbPromise = await Db.find({accountStatus:"active"}).distinct('_id');
// Solving the Promise (can be solved later in the code)
const ids = dbPromise.then(ids => {
   // Same logic as in Method 1
   let strArr = [];
   for (let id of ids){
      strArr.push(id.str);
   }
   return strArr;
};

Useful readings:

2 Comments

Thanks, @Go_dot! I have upvoted your answer. Glad to be your first up-voter ;)
Thanks for the upvote @Egidius <3 ! Even though Tobias' answer contains a much cleaner solution, I hope mine offered an interesting further reading. Wish u the best !

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.