mongodb mongoTemplate получить отдельное поле с некоторыми критериями

Моя структура MongoDB json:

 {
    "_id" : "122134231234234",
    "name" : "Total_pop",
    "description" : "sales category",
    "source" : "public",
    "dataset" :"d1"


},
{
    "_id" : "1123421231234234",
    "name" : "Total_pop",
    "description" : "sales category",
    "source" : "public",
    "dataset" :"d1"


},
{
    "_id" : "12312342332423343",
    "name" : "Total_pop",
    "description" : "sales category",
    "source" : "private",
    "description" : "d1"
}

Мне нужно получить коллекцию, отличную от набора данных, где источник является общедоступным. Я пробовал этот запрос, и он не работал:

Criteria criteria = new Criteria();
criteria.where("source").in("public");     
query.addCriteria(criteria);
query.fields().include("name");
query.fields().include("description");
query.fields().include("description");
query.fields().include("source"); List list =
mongoTemplate.getCollection("collectionname").distinct("source", query);

Не могли бы вы мне помочь?


person Raj    schedule 26.07.2015    source источник


Ответы (2)


Во-первых, метод .getCollection() возвращает базовый объект коллекции Driver следующим образом:

DBCollection collection = mongoTemplate.getCollection("collectionName");

Таким образом, тип объекта запроса может отличаться от того, который вы используете, но есть и другие вещи. А именно, что .distinct() возвращает только «отдельные» значения ключа, который вы запросили, и не возвращает другие поля документа. Итак, вы можете сделать:

Criteria criteria = new Criteria();
criteria.where("dataset").is("d1");
Query query = new Query();
query.addCriteria(criteria);
List list = mongoTemplate.getCollection("collectionName")
    .distinct("source",query.getQueryObject());

Но это только вернет «образец» как один элемент в списке, например.

Если вам нужны «поля» из отдельного набора, используйте вместо этого метод .aggregate(). Либо с «первыми» вхождениями других значений поля для отдельного ключа:

    DBCollection colllection = mongoTemplate.getCollection("collectionName");

    List<DBObject> pipeline = Arrays.<DBObject>asList(
        new BasicDBObject("$match",new BasicDBObject("dataset","d1")),
        new BasicDBObject("$group",
            new BasicDBObject("_id","$source")
                .append("name",new BasicDBObject("$first","$name"))
                .append("description", new BasicDBObject("$first","$description"))
        )
    );

    AggregationOutput output = colllection.aggregate(pipeline);

Или фактические «различные» значения нескольких полей, сделав их частью ключа группировки:

    DBCollection colllection = mongoTemplate.getCollection("collectionName");

    List<DBObject> pipeline = Arrays.<DBObject>asList(
        new BasicDBObject("$match",new BasicDBObject("dataset","d1")),
        new BasicDBObject("$group",
            new BasicDBObject("_id",
                new BasicDBObject("source","$source")
                    .append("name","$name")
                    .append("description","$description")
            )
        )
    );

    AggregationOutput output = colllection.aggregate(pipeline);

Также уже существует прямой метод .aggregate() для экземпляров mongoTemplate, который имеет ряд вспомогательных методов для построения конвейеров. Но это должно указать вам в правильном направлении по крайней мере.

person Blakes Seven    schedule 26.07.2015
comment
В моем случае это не работает: mongoTemplate.getCollection("collectionName") .distinct("source",query.getQueryObject()); - person Pra_A; 04.04.2019

Начиная с Spring Data Mongo 2.2.0 MongoTemplate предоставляет функцию для извлечения отдельного поля с критериями,

Criteria criteria = new Criteria("country").is("IN");
Query query = new Query();
query.addCriteria(criteria);
return mongoTemplate.findDistinct(query,"city",Address.class,String.class);

Что в основном находит все отдельные города в наборе адресов, где страна находится в IN.

person user3009002    schedule 06.06.2019