Mongodb $ поиск в данных Spring монго

Я новый Mongodb, и у меня проблема с $lookup с java spring.

Я хотел бы использовать эту оболочку в данных Spring

db.NewFeed.aggregate([
    {
        $match : {username : "user001"}
    },
    {
      $lookup:
        {
          from: "NewfeedContent",
          localField: "content.contentId",
          foreignField: "_id",
          as: "NewfeedContent"
        }
   }
])

Я нашел в Google, но ответа пока нет.


person Anh Bui    schedule 22.03.2016    source источник
comment
есть ли ошибка? можешь объяснить что не работает?   -  person Sanj    schedule 22.03.2016


Ответы (5)


Не каждая «новая» функция сразу превращается в уровни абстракции, такие как весна-монго.

Поэтому вместо этого все, что вам нужно сделать, это определить класс, который использует интерфейс AggregationOperation, который вместо этого будет принимать объект BSON, указанный непосредственно как его содержимое:

public class CustomAggregationOperation implements AggregationOperation {
    private DBObject operation;

    public CustomAggregationOperation (DBObject operation) {
        this.operation = operation;
    }

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return context.getMappedObject(operation);
    }
}

Затем вы можете использовать в своей агрегации следующее:

Aggregation aggregation = newAggregation(
    match(
        Criteria.where("username").is("user001")
    ),
    new CustomAggregationOperation(
        new BasicDBObject(
            "$lookup",
            new BasicDBObject("from", "NewFeedContent")
                .append("localField","content.contentId")
                .append("foreignField", "_id")
                .append("as", "NewFeedContent")
        )
    )
)

Который показывает пользовательский класс, смешанный со встроенным помощником конвейера match().

Все, что происходит под каждым помощником, это то, что они сериализуются в представление BSON, например, с DBObject в любом случае. Таким образом, конструктор здесь просто берет объект напрямую и возвращает его непосредственно из .toDBObject(), что является стандартным методом интерфейса, который будет вызываться при сериализации содержимого конвейера.

person Blakes Seven    schedule 22.03.2016
comment
Spring Data Mongo теперь поддерживает операции поиска docs.spring.io/spring-data/mongodb/docs/ 1.10.x/api/org/ - person macias; 31.10.2017
comment
В Spring Boot 2.x и spring-data-mongodb 2.0 объект DBObject был заменен на Document. Вы также должны заменить toDBObject() на toDocument(). См. docs.spring.io/spring-data/data-mongo/docs/current/reference/ - person jchrbrt; 31.05.2018

Объединение двух коллекций с Spring Data MongoDB

Класс сотрудника

class Employee {
    private String _id;
    private String name;
    private String dept_id;
}

Класс отдела

class Department {
    private String _id;
    private String dept_name;
}

Класс результатов сотрудников

public class EmpDeptResult {

    private String _id;
    private String name;
    private List<Object> departments;
}

Класс обслуживания сотрудников

public class EmployeeService {

    @Autowired
    private MongoTemplate mongoTemplate;

    private Logger LOGGER = LoggerFactory.getLogger(EmployeeService.class);

    public void lookupOperation(){
    LookupOperation lookupOperation = LookupOperation.newLookup()
                        .from("Department")
                        .localField("dept_id")
                        .foreignField("_id")
                        .as("departments");

    Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("_id").is("1")) , lookupOperation);
        List<EmpDeptResult> results = mongoTemplate.aggregate(aggregation, "Employee", EmpDeptResult.class).getMappedResults();
        LOGGER.info("Obj Size " +results.size());
    }
}
person Dhiren Chauhan    schedule 29.03.2018
comment
я хочу присоединиться к нескольким полям, есть ли способ? - person Arun Pratap Singh; 04.07.2018

Вот пример:

Коллекция сообщений

{
"_id" : ObjectId("5a198074ed31adaf5d79fe8a"),
"title" : "Post 1",
"authors" : [1, 2]
},
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8d"),
"title" : "Post 2",
"authors" : [2]
}

Сбор пользователей

{
"_id" : ObjectId("5a18b483ed31ada08fd6ed82"),
"userId" : 1,
"name" : "Vinod Kumar"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed83"),
"userId" : 2,
"name" : "Jim Hazel"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed84"),
"userId" : 3,
"name" : "Alex Wong"
}

Запрос MongoDB с поиском и сопоставлением

db.users.aggregate([
{
  $lookup:
    {
      from: "users",
      localField: "userid",
      foreignField: "authors",
      as: "post"
    }
  },
  {
     $match: { "post": { $ne: [] } }
  }
]).pretty()

Синтаксис Spring Mongoopration

LookupOperation lookupOperation = LookupOperation.newLookup().
            from("posts").
            localField("userid").
            foreignField("authors").
            as("post");

AggregationOperation match = Aggregation.match(Criteria.where("post").size(1));


Aggregation aggregation = Aggregation.newAggregation(lookupOperation, match);

List<BasicDBObject> results = mongoOperation.aggregate(aggregation, "users", BasicDBObject.class).getMappedResults();
person VK321    schedule 26.11.2017

Слишком поздно отвечать на этот вопрос, но это может помочь другим, кто сталкивается с той же проблемой. Если вы используете версию spring-boot-data-mongodb-2.0 или выше, то есть простой способ реализовать это.

AggregationOperation match = Aggregation.match(Criteria.where("username").is("user001")));
AggregationOperation query = Aggregation.lookup("NewfeedContent", "content.contentId", "_id", "NewfeedContent");
// If you want to unwind
//AggregationOperation unwind = Aggregation.unwind("Patient");
Aggregation agr = Aggregation.newAggregation(query, match, unwind);
AggregationResults<Document> result = springTemplate.aggregate(agr, "CollectionName", Document.class);
person Vivek Singh    schedule 17.10.2019

Можно использовать ниже, чтобы присоединиться к 3 коллекциям

MongoClient mongoClient = new MongoClient( "localhost" , 27017 );

DB db = mongoClient.getDB( "DBname" );

BasicDBObject query = BasicDBObject.parse("{$match:{_id:61188}},\n" +
        "   {\n" +
        "     $lookup:\n" +
        "       {\n" +
        "         from: \"CustomerDetails\",\n" +
        "         localField: \"supplierId\",\n" +
        "         foreignField: \"supplierId\",\n" +
        "         as: \"newfield\"\n" +
        "       }\n" +
        "  }\n" +
        "  ,  {\n" +
        "     $lookup:\n" +
        "       {\n" +
        "         from: \"ItemDetails\",\n" +
        "         localField: \"supplierId\",\n" +
        "         foreignField: \"supplierId\",\n" +
        "         as: \"newfield\"\n" +
        "       }\n" +
        "  }");

AggregationOutput dumps = db.getCollection("HeaderInfo").aggregate(query);

System.out.println("result="+dumps.results());
person vinay jain    schedule 18.07.2019
comment
Невозможно отправить два объекта $lookup в методе синтаксического анализа, он рассматривает только один объект поиска. пожалуйста помоги - person Rajesh Khore; 27.12.2019