2
votes

I'm getting distinct values of field from mongodb. When i run the following query in the commandline, it works good. db.celldata.distinct("tenentId")

I'm using Mongo java 3.0 driver, to retrieve the distinct values using the following query MongoCursor<String> iterator = coll.distinct("tenantId", String.class).iterator();

When i run the query i get the following exception org.bson.BsonInvalidOperationException: readString can only be called when CurrentBSONType is STRING, not when CurrentBSONType is NULL.

1

1 Answers

4
votes

Well, the root cause of the error here is because you have a String type as expected output and one of the distinct values is actually null. The way I see it you have two ways of working with this.

Also noting that an "iterator" is overkill for a "distinct" list generally speaking, so just go straight to ArrayList.

Either .filter() out the unwanted null values:

    ArrayList<String> distinct = coll.distinct("tenantId", String.class)
            .filter(new Document("tenantId",new Document("$ne",null)))
            .into(new ArrayList<String>());

    System.out.println(distinct);

Or accept the results as BsonValue and handle those:

    ArrayList<BsonValue> distinct = coll.distinct("tenantId", BsonValue.class)
            .into(new ArrayList<BsonValue>());

    System.out.println(distinct);

But in the latter case, you still need to handle the types returned. There are methods on BsonValue to allow you to code for this, but it is also a fair bit of overkill for just getting a list of distinct values.

Therefore as a "third" option, I would go for something with an "un-typed" response. The .aggregate() method works will here, but it will be BSON documents in the response, it is still up to you to transfer to a plain ArrayList of different types:

    ArrayList<Object> objects = new ArrayList<Object>();

    MongoCursor<Document> iterator = coll.aggregate(Arrays.asList(
            new Document("$group",
                    new Document("_id", "$tenantId")
            )
    )).iterator();

    while (iterator.hasNext()) {
        objects.add(iterator.next().get("_id"));
    }

    System.out.println(objects);