Как выполнить агрегационный запрос Mon go в Spring Data? - PullRequest
0 голосов
/ 11 января 2020

Я впервые использую Mon go в Java, и у меня возникли некоторые проблемы с этим запросом агрегации. Я могу сделать несколько простых запросов в Mon go для Spring с аннотацией @Query в моем интерфейсе репозитория, который расширяет MongoRepository<T, ID>. Было бы полезно узнать, какой подход использовать при длинных агрегациях в Spring-Data.

db.post.aggregate([
    {
      $match: {}
    },
    {
      $lookup: {
        from: "users",
        localField: "postedBy",
        foreignField: "_id",
        as: "user"
      }
    },
    {
      $group: {
        _id: {
          username: "$user.name",
          title: "$title",
          description: "$description",
          upvotes: { $size: "$upvotesBy" },
          upvotesBy: "$upvotesBy",
          isUpvoted: { $in: [req.query.userId, "$upvotesBy"] },
          isPinned: {
            $cond: {
              if: { $gte: [{ $size: "$upvotesBy" }, 3] },
              then: true,
              else: false
            }
          },
          file: "$file",
          createdAt: {
            $dateToString: {
              format: "%H:%M %d-%m-%Y",
              timezone: "+01",
              date: "$createdAt"
            }
          },
          id: "$_id"
        }
      }
    },
    { $sort: { "_id.isPinned": -1, "_id.createdAt": -1 } }
])

1 Ответ

3 голосов
/ 14 января 2020

Вы можете реализовать AggregationOperation и написать запрос пользовательской операции агрегирования, а затем использовать MongoTemplate для выполнения любого запроса оболочки mon go, который вы выполнили в своей оболочке mon go, как показано ниже:

Пользовательская операция агрегирования

import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;

public class CustomAggregationOperation implements AggregationOperation {

  private String jsonOperation;

  public CustomAggregationOperation(String jsonOperation) {
    this.jsonOperation = jsonOperation;
  }

  @Override
  public org.bson.Document toDocument(AggregationOperationContext aggregationOperationContext) {
    return aggregationOperationContext.getMappedObject(org.bson.Document.parse(jsonOperation));
  }
}

Любой понедельник go Исполнитель запроса агрегации оболочки

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.stereotype.Service;
import sample.data.mongo.models.Course;

@Service
public class LookupAggregation {

  @Autowired
  MongoTemplate mongoTemplate;

  public void LookupAggregationExample() {

    AggregationOperation unwind = Aggregation.unwind("studentIds");

    String query1 = "{$lookup: {from: 'student', let: { stuId: { $toObjectId: '$studentIds' } },"
        + "pipeline: [{$match: {$expr: { $eq: [ '$_id', '$$stuId' ] },},}, "
        + "{$project: {isSendTemplate: 1,openId: 1,stu_name: '$name',stu_id: '$_id',},},], "
        + "as: 'student',}, }";

    TypedAggregation<Course> aggregation = Aggregation.newAggregation(
        Course.class,
        unwind,
        new CustomAggregationOperation(query1)
    );

    AggregationResults<Course> results =
        mongoTemplate.aggregate(aggregation, Course.class);
    System.out.println(results.getMappedResults());
  }
}

Подробнее , Посмотрите на Github репозиторий классы: CustomAggregationOperation & LookupAggregation

Другие подходы также с использованием MongoTemplate :

# 1. Определить интерфейс для пользовательского кода для модели Post :

interface CustomPostRepository {
     List<Post> yourCustomMethod();
}

# 2. Добавьте реализацию для этого класса и следуйте соглашению об именах, чтобы убедиться, что мы можем найти этот класс.

class CustomPostRepositoryImpl implements CustomPostRepository {

    @Autowired
    private MongoOperations mongoOperations;

    public List<Post> yourCustomMethod() {

      // custom match queries here
      MatchOperation match = null;
      // Group by , Lookup others stuff goes here
      // For details: https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/aggregation/Aggregation.html

      Aggregation aggregate = Aggregation.newAggregation(match);

      AggregationResults<Post> orderAggregate = mongoOperations.aggregate(aggregate,
                      Post.class, Post.class);
      return orderAggregate.getMappedResults();

    }
}

# 3. Теперь позвольте вашему базовому интерфейсу репозитория расширить custom и инфраструктура будет автоматически использовать вашу пользовательскую реализацию:

interface PostRepository extends CrudRepository<Post, Long>, CustomPostRepository {

}
...