使用mongo Java Driver 3.0从Mongo集合中获取字段的不同值时发生异常

使用mongo Java Driver 3.0从Mongo集合中获取字段的不同值时发生异常

问题描述:

我从mongodb中获得了不同的字段值. 当我在命令行中运行以下查询时,效果很好. db.celldata.distinct("tenentId")

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")

我正在使用Mongo Java 3.0驱动程序,使用以下查询来检索不同的值 MongoCursor<String> iterator = coll.distinct("tenantId", String.class).iterator();

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();

当我运行查询时,出现以下异常 org.bson.BsonInvalidOperationException: readString can only be called when CurrentBSONType is STRING, not when CurrentBSONType is NULL.

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.

好吧,此错误的根本原因是因为您具有String类型作为预期输出,而不同的值之一实际上是null.从我的角度来看,您有两种处理方式.

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.

还要注意,通常来说,迭代器"对于独特"列表是过大的,所以直接进入ArrayList.

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

.filter()中的任何一个.filter()都将删除不必要的null值:

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);

或接受结果作为BsonValue并处理这些结果:

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);

但是在后一种情况下,您仍然需要处理返回的类型. BsonValue上有一些方法可以让您对此进行编码,但是对于仅获取不同值的列表来说,这也有些过分.

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.

因此,作为第三个"选项,我会选择带有未键入"响应的内容. .aggregate()方法将在这里工作,但是它将是BSON文档的响应,仍然需要您将其转移到不同类型的普通ArrayList上:

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);