【问题标题】:MongoDB Java: Finding objects in Mongo using QueryBuilder $in operator returns nothingMongoDB Java:使用 QueryBuilder $in 运算符在 Mongo 中查找对象不返回任何内容
【发布时间】:2012-07-25 13:34:55
【问题描述】:

我有一个称为MongoRuleJUnit rule 看起来像

public class MongoRule extends ExternalResource {

    private static final Logger LOGGER = LoggerFactory.getLogger(MongoRule.class);
    private final MongoService mongoService;

    public MongoRule() throws UnknownHostException {
        mongoService = new MongoService(getConfiguredHost(), getConfiguredPort(), getConfiguredDatabase());
    }

    @Override
    protected void before() throws Throwable {
        LOGGER.info(" Setting up Mongo Database - " + getConfiguredDatabase());
    }

    @Override
    protected void after() {
        LOGGER.info("Shutting down the Mongo Database - " + getConfiguredDatabase());
        mongoService.getMongo().dropDatabase(getConfiguredDatabase());
    }

    @Nonnull
    public DB getDatabase() {
        return mongoService.getMongo().getDB(getConfiguredDatabase());
    }

    @Nonnull
    public Mongo getMongo() {
        return mongoService.getMongo();
    }

    @Nonnull
    public MongoService getMongoService() {
        return mongoService;
    }

    public static int getConfiguredPort() {
        return Integer.parseInt(System.getProperty("com.db.port", "27017"));
    }

    @Nonnull
    public static String getConfiguredDatabase() {
        return System.getProperty("com.db.database", "database");
    }

    @Nonnull
    public static String getConfiguredHost() {
        return System.getProperty("com.db.host", "127.0.0.1");
    }
}

然后我尝试插入一些文档如下

 public static void saveInDatabase() {
        LOGGER.info("preparing database - saving some documents");
        mongoRule.getMongoService().putDocument(document1);
        mongoRule.getMongoService().putDocument(document2);
    }

其中document1document2 是有效的DBObject 文档。架构看起来像

{
    Id: 001
    date_created: 2012-10-31
    vars: {
      '1': {
           name: n1
           value:v1
       }
      '2': {
           name: n2
           value:v2
       }
      '3': {
           name: n3
           value:v3
       }

} 
{
    Id: 002
    date_created: 2012-10-30
    vars: {
      '1': {
           name: n4
           value:v4
       }
      '2': {
           name: n5
           value:v5
       }
      '3': {
           name: n6
           value:v6
       }

}

现在我尝试查询集合并获取这些对象,所以我这样做了

public static void getDocuments(List<String> documentIds) {
        BasicDBList docIds = new BasicDBList();
        for (String docId: documentIds) {
            docIds.add(new BasicDBObject().put("Id", docId));
        }
        DBObject query = new BasicDBObject();
        query.put("$in", docIds);
        DBCursor dbCursor = mongoRule.getDatabase().getCollection("mycollection").find(query);
        System.out.println(dbCursor == null);
        if (dbCursor != null) {
            while (dbCursor.hasNext()) {
                System.out.println("object -  " + dbCursor.next());
            }
        }
    }  

mycollection 是保存所有文档的集合,它来自外部服务。
当我运行此文档时,我看到以下内容

preparing database - saving some documents
inserting document - DBProposal # document1
inserting document - DBProposal # document2
false

这意味着collection.find() 找不到这些文档。

我在这里没有做什么?如何取回文件?

我对使用JavaMongo 非常陌生,并使用此reference 来构造查询

更新
改变查询的构造方式后,还是看不到文档

public static void getDocuments(List<String> documentIds) {
            BasicDBList docIds = new BasicDBList();
            docIds.addAll(documentIds)
            DBObject query = new BasicDBObject();
            query.put("$in", docIds);
            DBCursor dbCursor = mongoRule.getDatabase().getCollection("mycollection").find(query);
            System.out.println(dbCursor == null);
            if (dbCursor != null) {
                while (dbCursor.hasNext()) {
                    System.out.println("object -  " + dbCursor.next());
                }
            }
        } 

集合名称通过

返回
private static String getCollectionName(@Nonnull final DBObject dbObject) {
        return "mycollection";
    }

【问题讨论】:

  • 您能否也发布您的putDocument 代码 - 只需确保集合名称相同即可:)
  • 还要确保您至少使用 SAFE 写入问题,否则在执行查找之前写入可能尚未提交到内存,这意味着它不会找到任何文档。
  • 这不是一个有效的查询。我会发布回复。
  • @christkv,是的,默认写入关注点是 WriteConcern.SAFE
  • @Ross,我添加了返回集合名称的代码

标签: java mongodb mongo-java


【解决方案1】:

你现在做的相当于:

db.col.find({$in:[{Id:id1}, {Id:id2}, ..., {Id:idN}]})

这不是一个有效的查询,因为您没有指定 $in 的字段。我假设你想要:

db.col.find({Id:{$in:[id1, id2, ..., idN]}})

相应地更改您的查询构造代码,您应该没问题。

编辑:添加正确的代码:

public static void getDocuments(List<Integer> documentIds) {

            BasicDBList docIds = new BasicDBList();
            docIds.addAll(documentIds)
            DBObject inClause = new BasicDBObject("$in", docIds);
            DBObject query = new BasicDBObject("Id", inClause);
            DBCursor dbCursor = mongoRule.getDatabase().getCollection("mycollection").find(query);
            System.out.println(dbCursor == null);
            if (dbCursor != null) {
                while (dbCursor.hasNext()) {
                    System.out.println("object -  " + dbCursor.next());
                }
            }
        } 

请注意,这里假定“Id”不是“_id”

【讨论】:

  • 代码还是错误的。并添加一个示例文档,您的架构描述不明确。
  • 我更新了架构,感谢您的帮助,我仍然无法弄清楚如何正确执行此操作
  • 你试过我的代码了吗?只要您不提供 String put Integer 列表(您的架构使“Id”字段成为整数而不是字符串),它就可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多