【问题标题】:How to execute MongoDB native query (JSON) using mongo-java-driver only?如何仅使用 mongo-java-driver 执行 MongoDB 本机查询 (JSON)?
【发布时间】:2017-11-03 10:30:12
【问题描述】:

如何仅使用 java-mongo-driver 触发 mongo 本机查询。

Spring-Data 或 EclipseLink 或 Hibernate OGM,仅使用 java-mongo-driver

示例查询:

db.orders.aggregate([
   {
      $unwind: "$specs"
   },
   {
      $lookup:
         {
            from: "inventory",
            localField: "specs",
            foreignField: "size",
            as: "inventory_docs"
        }
   },
   {
      $match: { "inventory_docs": { $ne: [] } }
   }
])

【问题讨论】:

标签: json mongodb native mongo-java-driver


【解决方案1】:

如果您的问题是:

我可以将上面的字符串传递给Java驱动程序并让驱动程序执行它吗?

那么您可以使用db.eval 命令。例如:

MongoDatabase database = mongoClient.getDatabase("...");

Bson command = new Document("eval", "db.orders.aggregate([\n" +
        "   {\n" +
        "      $unwind: \"$specs\"\n" +
        "   },\n" +
        "   {\n" +
        "      $lookup:\n" +
        "         {\n" +
        "            from: \"inventory\",\n" +
        "            localField: \"specs\",\n" +
        "            foreignField: \"size\",\n" +
        "            as: \"inventory_docs\"\n" +
        "        }\n" +
        "   },\n" +
        "   {\n" +
        "      $match: { \"inventory_docs\": { $ne: [] } }\n" +
        "   }\n" +
        "])");
Document result = database.runCommand(command);

但是 ... db.eval 命令已被弃用,其用法为 is not advised。 MongoDB Java 驱动程序可用于执行聚合,但不能以“字符串形式”执行,而是使用 Java 驱动程序的聚合助手来创建聚合命令的 Java 形式。关于这个in the docs的大量细节。

这是一个使用 3.x MongoDB Java 驱动程序的(未经测试的)示例...

MongoCollection<Document> collection = mongoClient.getDatabase("...").getCollection("...");

AggregateIterable<Document> documents = collection.aggregate(Arrays.asList(
        // the unwind stage
        new Document("$unwind", "$specs"),

        // the lookup stage
        new Document("$lookup", new Document("from", "inventory")
                .append("localField", "specs")
                .append("foreignField", "size")
                .append("as", "inventory_docs")),

        // the match stage
        new Document("$match", new Document("inventory_docs", new BasicDBObject("$ne", new String[0])))
));

.. 这可能有助于您了解从 shell 脚本到 Java 的转换形式。

【讨论】:

    【解决方案2】:

    我的时间不多了,所以使用了以下解决方法。 稍后将详细探讨 Morcos 的建议。 但是下面的代码也可以。

    import com.infrasoft.mongo.MongoClientFactory;
    import com.mongodb.BasicDBList;
    import com.mongodb.BasicDBObject;
    import com.mongodb.CommandResult;
    import com.mongodb.DB;
    import com.mongodb.DBObject;
    import com.mongodb.util.JSON;
    
    /**
     *
     * @author charudatta.joshi
     */
    public class TestNaiveQuery1 {
    
        public static void main(String[] args) {
    
            String nativeQuery = "db.orders.aggregate([\n"
                    + "   {\n"
                    + "      $unwind: \"$specs\"\n"
                    + "   },\n"
                    + "   {\n"
                    + "      $lookup:\n"
                    + "         {\n"
                    + "            from: \"inventory\",\n"
                    + "            localField: \"specs\",\n"
                    + "            foreignField: \"size\",\n"
                    + "            as: \"inventory_docs\"\n"
                    + "        }\n"
                    + "   },\n"
                    + "   {\n"
                    + "      $match: { \"inventory_docs\": { $ne: [] } }\n"
                    + "   }\n"
                    + "])";
    
            DBObject command = new BasicDBObject();
            DB db = MongoClientFactory.getMongoClientFactory().getMongoClient().getDB("frms_data_demo");
    
            nativeQuery = "function() { return (" + nativeQuery + ").toArray(); }";
    
            //command.put("eval", "function() { return db." + collectionName + ".find(); }");
            command.put("eval", nativeQuery);
            CommandResult result = db.command(command);
    
            BasicDBList dbObjList = (BasicDBList) result.toMap().get("retval");
    
            DBObject dbo0 = (BasicDBObject) dbObjList.get(0);
            DBObject dbo1 = (BasicDBObject) dbObjList.get(0);
    
            System.out.println(dbObjList.get(0));
            System.out.println(dbObjList.get(1));
            // .... just loop on dbObjList
    
        }
    
    
    }
    

    【讨论】:

      【解决方案3】:

      此查询自 3.0 版以来已弃用。 https://docs.mongodb.com/manual/reference/method/db.eval/,我用的是mongodb4.0集群,不支持eval函数,

      【讨论】:

      • 有没有其他办法解决,谢谢!@Charudatta Joshi
      • 提供代码示例。在此处发布问题之前,请了解如何提出问题以获得可靠的答案。参考这个:stackoverflow.com/help/how-to-ask
      【解决方案4】:

      @aaronwang4love 你可以试试下面的代码。 未测试。现在无法访问环境。如果有效,请更新。

      BasicDBObject query = BasicDBObject.parse("{userId: {$gt: \"1\"}}"); 
      FindIterable<Document> dumps = crapCollection.find(query);
      


      或者你也可以使用 com.mongodb.util.JSON

      DBObject dbObject = (DBObject)JSON.parse("{userId: {$gt: \"1\"}}");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-22
        • 2021-01-29
        • 2019-06-30
        • 1970-01-01
        • 1970-01-01
        • 2013-06-23
        • 1970-01-01
        • 2021-04-28
        相关资源
        最近更新 更多