如何将Mongo Document转换为java Set <string>?

时间:2017-09-23 20:53:54

标签: java mongodb

我已将Set<String>保存为mongodb作为数组,之后我想再将其加载到Set<String>。怎么做?

我的尝试返回异常:

package Database;

import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;

import java.util.HashSet;
import java.util.Set;

import org.bson.Document;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public class StackOverflow {

    public static void main(String[] args) {

        // insert something to mongo:
        final String URI = "mongodb://localhost:27017";
        final String DB = "StackOverflowQuestion";
        final String COLLECTION = "eqDoesntExcist";

        MongoClientURI connection = new MongoClientURI(URI);
        MongoClient mongo = new MongoClient(connection);
        MongoDatabase database = mongo.getDatabase(DB);
        MongoCollection<Document> collection = database.getCollection(COLLECTION);

        Set<String> namesOfTroysKids = new HashSet<>();
        namesOfTroysKids.add("Paul");
        namesOfTroysKids.add("Jane");
        namesOfTroysKids.add("Mark");
        namesOfTroysKids.add("Ivona");

        Document doc = new Document("name", "Troy").append("height", 185).append("kids", namesOfTroysKids);
        collection.insertOne(doc);

        // read something from mongo
        FindIterable<Document> findIt = collection.find(eq("name", "Troy")).projection(fields(include("kids")));
        Document d = findIt.first();

        Set<String> kids = (Set<String>) d; // ERROR !!!
        ///Exception in thread "main" java.lang.ClassCastException: org.bson.Document cannot be cast to java.util.Set
        //at Database.StackOverflow.main(StackOverflow.java:45)

    }

}

有方法toArray(),但它适用于折旧的DBObject。

2 个答案:

答案 0 :(得分:1)

基本上,Iterable类型是需要循环的东西。如果使用Iterable类型打开游标,则将其分配给java数据类型的唯一方法是获取一次迭代。您已经通过使用第一个方法来完成此操作,该方法将获取查询返回的第一个文档,请注意,如果您打算这样做,则可以使用sort来控制返回哪个Document。

以下是代码。当我这样做时,除了在开始处理之前我需要整个数据集之外,我通常会逐一对数据做任何我需要的事情。

Set<String> kids = new Set<String>;    
for(Document kidDoc :  collection.find(eq("name", "Troy"))){
        kids.add(kidDoc.getString("kids")))
}

答案 1 :(得分:1)

您的查询返回的文件是:

{
   "_id": {
      "$oid": "_id_value_"
   },
   "kids": [
      "Mark",
      "Ivona",
      "Paul",
      "Jane"
   ]
}

显然不能隐含地强制进入集合。它现在只需要从文档中获取孩子作为列表并从中实例化一个Set:

public static void main(String [] args) throws Exception  {
    final String URI = "mongodb://localhost:27017";            
    final String DB = "StackOverflowQuestion";
    final String COLLECTION = "eqDoesntExcist";

    MongoClientURI connection = new MongoClientURI(URI);
    MongoClient mongo = new MongoClient(connection);
    MongoDatabase database = mongo.getDatabase(DB);
    MongoCollection<Document> collection = database.getCollection(COLLECTION);

    Set<String> namesOfTroysKids = new HashSet<>();
    namesOfTroysKids.add("Paul");
    namesOfTroysKids.add("Jane");
    namesOfTroysKids.add("Mark");
    namesOfTroysKids.add("Ivona");

    Document doc = new Document("name", "Troy").append("height", 185).append("kids", namesOfTroysKids);
    collection.insertOne(doc);

    // read something from mongo
    FindIterable<Document> findIt = collection.find(Filters.eq("name", "Troy")).projection(Projections.include("kids"));
    Document d = findIt.first();

    System.out.println("doc: " + d.toJson());

    List<String> kidsList = (List<String>) d.get("kids", List.class);

    Set<String> kidsSet = new HashSet<>(kidsList);

    System.out.println("kids: " + kidsSet);
}