如何直接从 Java 中的 mongodb 查询返回原始 JSON?

Posted

技术标签:

【中文标题】如何直接从 Java 中的 mongodb 查询返回原始 JSON?【英文标题】:How to return raw JSON directly from a mongodb query in Java? 【发布时间】:2013-08-20 16:50:39 【问题描述】:

我有以下代码:

@RequestMapping(value = "/envinfo", method = RequestMethod.GET)
@ResponseBody
public Map getEnvInfo()

    BasicQuery basicQuery = new BasicQuery("_id:'51a29f6413dc992c24e0283e'", "'envinfo':1, '_id': false ");
    Map envinfo= mongoTemplate.findOne(basicQuery, Map.class, "jvmInfo");
    return envinfo;

如你所见,代码:

    从 MongoDB 检索 JSON 将其转换为Map 对象 Map 对象随后由 Spring MongoData 转换为 JSON,然后返回给浏览器。

是否可以直接从MongoDb返回原始json而不经过中间转换步骤?

【问题讨论】:

【参考方案1】:

对我来说,以下工作完美:

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.bson.Document;

List<Document> documents = mongoTemplate.find(query, Document.class, "collection_name");

【讨论】:

【参考方案2】:

正如 Oliver 指出的那样,您可以为此使用 Spring Data,但您可能更喜欢也可能不喜欢的替代方法是使用 MongoDB 的更底层的 Java 驱动程序。请查看 MongoDB Java Driver 3.x 或 MongoDB Java Driver 2.x 文档以获取有关使用该驱动程序的说明。

基本上,你需要做的是:

MongoDB Java 驱动程序 3.x

MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("test");
MongoCollection coll = db.getCollection("testCollection");    
BasicDBObject query = new BasicDBObject("_id", "51a29f6413dc992c24e0283e");

try (MongoCursor<Document> cursor = collection.find(query).iterator()) 
    while(cursor.hasNext()) 
        System.out.println(cursor.next());
    

MongoDB Java 驱动程序 2.x

MongoClient mongoClient = new MongoClient();
DB db = mongoClient.getDB("test");
DBCollection coll = db.getCollection("testCollection");    
BasicDBObject query = new BasicDBObject("_id", "51a29f6413dc992c24e0283e");

try (DBCursor cursor = coll.find(query)) 
    while(cursor.hasNext()) 
        System.out.println(cursor.next());
    

这将打印出集合中具有字段_id 和值51a29f6413dc992c24e0283e 的所有文档。

【讨论】:

有人否决了这个?有兴趣知道它有什么问题。我没有测试它,但它实际上是从文档中复制粘贴的。 有三个方面:第一,不是Spring Data做不到。我正要准备一个答案,看看它是如何工作的。其次,您正在将内容转储到标准输出,而不是返回String。第三,您的代码没有处理任何异常等。我知道这是示例代码,但是您可以立即使用 if 您使用 Spring Data,因此在使用 Spring Data 实现其他所有内容的场景中使用您的代码会导致行为不一致。 如果您可以使用 spring 数据来做到这一点,那么看看您如何使用它会很有趣。至于返回一个字符串,而不是处理异常,这些都是微不足道的。任何称职的程序员都可以弄清楚如何返回cursor.next() 的结果,而不是系统输出它。 明白了。一般来说,您显示的代码没有任何问题。只是人们希望在使用 SD MongoDB(异常翻译等)时获得某些行为,而您的示例没有获得这些行为。由于原始发布者似乎在他的代码中使用 SD MongoDB 并且明确要求它,我认为“你应该使用其他东西”不是处理它的好方法。这就像有人要一个 android 应用程序,你告诉他“买一个 iPhone”:)。没有冒犯的意思!我刚刚发布了我的答案:简而言之 - 它会在一段时间内运行 OOTB,但现在可以轻松实现。【参考方案3】:

现在有两种方法可以做到这一点:

1。在MongoTemplate 上使用CollectionCallback

你可以直接使用CollectionCallback来处理返回的DBObject,简单的toString()它:

template.execute("jvmInfo", new CollectionCallback<String>() 
  String doInCollection(DBCollection collection) 
    DBCursor cursor = collection.find(query)
    return cursor.next().toString()
  

您仍然可以将异常翻译成 Spring 的 DataAccessExceptions。请注意,这有点脆弱,因为我们希望查询只返回一个结果,但这可能是您在尝试生成 String 时必须注意的事情。

2。将ConverterDBObject注册到String

您可以实现一个 Spring Converter 来为您执行 toString()

class DBObjectToStringConverter implements Converter<DBObject, String> 
  public String convert(DBObject source) 
    return source == null ? null : source.toString();
  

然后您可以使用 XML 配置或覆盖 customConversions() 以返回 new CustomConversions(Arrays.asList(new DBObjectToStringConverter())) 以将其注册到您的 MongoConverter。然后,您可以简单地执行以下操作:

String result = mongoTemplate.findOne(basicQuery, String.class, "jvmInfo");

我会将刚刚展示的转换器添加到 Spring Data MongoDB 并默认为即将发布的 1.3 GA 版本注册它,并将修复移植回 1.2.x,作为修复 DATAMONGO-743 的一部分。

【讨论】:

我有一个问题!我可以用 MongoRepository 做同样的事情吗?

以上是关于如何直接从 Java 中的 mongodb 查询返回原始 JSON?的主要内容,如果未能解决你的问题,请参考以下文章

怎么在java中获得mongodb分组group的结果中的总数量

java如何实现mongodb中查询指定字段?

如何从 mongodb 查询和获取数组中的一项?

如何使用聚合从 mongodb 中的两个集合中查询?

如何使用 Java 中的 ObjectID 更新 MongoDB 中的文档

如何从 MongoDB 中的数组中查询具有最新日期的对象?