MongoDB Java: поиск объектов в Mongo с использованием оператора QueryBuilder $in ничего не возвращает

У меня есть JUnit rule, так как MongoRule выглядит так

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

Где document1 и document2 действительные 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() не смог найти эти документы.

Что я тут не так делаю? Как мне вернуть документы?

Я новичок в использовании Java с Mongo и использовал этот ссылка построить запрос

ОБНОВЛЕНИЕ
После изменения способа построения запроса я по-прежнему не вижу документы

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";
    }

person daydreamer    schedule 25.07.2012    source источник
comment
Можете ли вы также опубликовать свой код putDocument - просто убедитесь, что имена коллекций совпадают :)   -  person Ross    schedule 25.07.2012
comment
Также убедитесь, что вы используете проблему записи как минимум SAFE, иначе записи могут не быть зафиксированы в памяти до выполнения поиска, что означает, что он не найдет никаких документов.   -  person christkv    schedule 25.07.2012
comment
Это неверный запрос. Я опубликую ответ.   -  person Remon van Vliet    schedule 25.07.2012
comment
@christkv, да, проблема записи по умолчанию — WriteConcern.SAFE   -  person daydreamer    schedule 25.07.2012
comment
@Ross, я добавил код, который возвращает имя коллекции   -  person daydreamer    schedule 25.07.2012


Ответы (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».

person Remon van Vliet    schedule 25.07.2012
comment
Код по-прежнему неверен. И добавьте образец документа, ваше описание схемы неоднозначно. - person Remon van Vliet; 26.07.2012
comment
Схему обновил, спасибо за помощь, пока не могу понять как правильно это сделать - person daydreamer; 26.07.2012
comment
Вы пробовали мой код? Это работает, если вы не предоставляете список строк, помещающих целое число (ваша схема делает поля идентификатора целым числом, а не строкой). - person Remon van Vliet; 27.07.2012