Realm count objects in collection

Hi all,

I’m creating an iOS app in Swift.
I have a collection with a lot of objects. Is there a way to count all the objects of this collection without getting/loading them?

Thanks for your help!

Hi @Julien_Chouvet, as you mention “collection”, I assume that the data is stored in Atlas and you don’t want to load it all into your mobile Realm database.

If this is the case, then you could create a Realm function such as this:

exports = function() {
  const db = context.services.get("mongodb-atlas").db("RChat");
  const chatCollection = db.collection("ChatMessage");
  
  return chatCollection.count()
  .then(result => {
    return result
  }, error => {
    console.log(`Failed to count ChatMessage documents: ${error}`);
  });
}; 

and then you can invoke that function from the iOS app: https://docs.mongodb.com/realm/sdk/ios/examples/call-a-function/

2 Likes

Perfect!

Thanks a lot!

Hi again !

@Andrew_Morgan I tried your solution which works fine.
I tied to filter the objects in my collection to only return the number of objects matching some criteria. I tried the following code:

exports = function(year){
const user = context.user;

const db = context.services.get(“mongodb-atlas”).db(“Customers”);
const customersCollection = db.collection(“Customers”);

const test = customersCollection.find({ firstName: “Julien” });

console.log("test = ", test);

return 0
};

In the Realm logs I have the following result:

[
“test = [object Object]”
]

How can I see the objects resulting from the filter function?
I tried:
console.log("test = ", test[0]);

And got:

[
“test = undefined”
]

I also tried to get only one result with findOne() and access my customer parameters but still got “undefined”.

const test = customersCollection.findOne();
console.log("test = ", test.firstName);
and
console.log("test = ", test[“firstName”]);

Moreover, when I return test and display the result in my iOS app, I got the following:

document([“_id”: Optional(RealmSwift.AnyBSON.objectId(60154fe947e22b1d7b3ce126)), “firstName”: Optional(RealmSwift.AnyBSON.string(“Julien”))])

And when I return test.firstName or test.["firstName"]:

document([“$undefined”: Optional(RealmSwift.AnyBSON.bool(true))])

Thanks for your help!

customersCollection.find is an asynchronous call, and your console.log call is executing before the database has returned any results. The database returns a promise that resolves once the request has completed. You need to add a .then clause that will run once the database request completes (the promise then resolves). Something like this…

return customersCollection.find({ firstName: “Julien” })
.then (result => {
    // work with the results
   return something
})

This is working with findOne() but with find() I have the error Function call failed: TypeError: 'then' is not a function.
I searched why is this error happening and apparently find() is not async.

Sorry - find returns a cursor which you can them map to an array (which is what returns a promise)…

return customersCollection.find({ firstName: “Julien” }).toArray()
.then (result => {
    // work with the results
   return something
})

Thanks! The then() function is working now. I just have a last problem, when I use findOne() I’m able to get an attribute like this:

return customersCollection.findOne()
  .then (result => {
    console.log('test = ', result.lastName);
    return result
  })

However, when I use find().toArray() I got undefined:

return customersCollection.find({ firstName: “Julien” }).toArray()
.then (result => {
console.log('test = ', result.lastName);
return result.lastName
})

result is an array and so you’ll need to index into it.

Of course! That was a stupid question sorry.

Thanks a lot for your help!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.