Skip to content

Instantly share code, notes, and snippets.

@vpiotr
Last active February 28, 2022 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vpiotr/9122fff78fb730c19ae9ed6ff7a9216e to your computer and use it in GitHub Desktop.
Save vpiotr/9122fff78fb730c19ae9ed6ff7a9216e to your computer and use it in GitHub Desktop.

Annotations

Spring Data - Document

@Document - specify collection @Field - specify column (field) name @Indexed - add field to index @TextIndexed - full text index @Transient - do not store @DBRef - ref @PersistentConstructor - use this constractor for deserialization

Spring Data - Repository

@Repository @Query

	@Query("{ 'name' : ?0 }")
	List<User> findUsersByName(String name);

	@Query("{ 'name' : { $regex: ?0 } }")
	List<User> findUsersByRegexpName(String regexp);
  
	@Query("{ 'age' : { $gt: ?0, $lt: ?1 } }")
	List<User> findUsersByAgeBetween(int ageGT, int ageLT);

MongoTemplate with Query and Criteria

  • Query
  • Criteria
  • MongoTemplate.find
  • PageRequest.of
  • Sort.by

Examples:

	Query query = new Query();
	query.addCriteria(Criteria.where("name").regex("c$"));
	List<User> users = mongoTemplate.find(query, User.class);

	Query query = new Query();
	query.with(Sort.by(Sort.Direction.ASC, "age"));
	List<User> users = mongoTemplate.find(query,User.class);

	final Pageable pageableRequest = PageRequest.of(0, 2);
	Query query = new Query();
	query.with(pageableRequest);

Query DSL

Maven: querydsl-mongodb https://mvnrepository.com/artifact/com.querydsl/querydsl-mongodb/4.1.4

QueryDslPredicateExecutor

	QUser qUser = new QUser("user");
	Predicate predicate = qUser.name.eq("Eric");
	List<User> users = (List<User>) userRepository.findAll(predicate);

Aggregates

in Mongo shell

Find avg from sub-array:

	db.legosets.aggregate([{
	  $project: {
		legoSetName: "$name",
		avgRating: {$avg: "$reviews.rating"}
	  }
	}])

in MongoTemplate

        ProjectionOperation projectToMatchModel = project()
                .andExpression("name").as("productName")
                .andExpression("{$avg : '$reviews.rating'}").as("avgRating");

        Aggregation avgRatingAggregation = newAggregation(LegoSet.class, projectToMatchModel);

        return this.mongoTemplate
                .aggregate(avgRatingAggregation, LegoSet.class, AvgRatingModel.class)
                .getMappedResults();

Full text search

  • annotate fields with @TextIndexed
  • create documents with MongoRepository
  • search with method in repository:
    // repository
	Collection<LegoSet> findAllBy(TextCriteria textCriteria);

    // controller
    @GetMapping("fullTextSearch/{text}")
    public Collection<LegoSet> fullTextSearch(@PathVariable String text) {
        TextCriteria textCriteria = TextCriteria.forDefaultLanguage().matching(text);
        return this.legoSetRepository.findAllBy(textCriteria);
    }  

DBRef

Find in Mongo shell

db.getCollecion("X").find({
  paymentOptions: {
	"$ref": "paymentOptions",
	"$id": ObjectId("5c...")
  }
})

in Spring Data @Repository/MongoRepository

@Query("{paymentOptions.id : ?0}")
Collection<LegoSet> findByPaymentOptionId(String id);

Data migrations

    @ChangeSet(order = "001", author = "ray", id = "update nb parts")
    public void updateNbOfParts(MongoTemplate mongoTemplate) {
        Criteria priceZeroCriteria = new Criteria().orOperator(
                Criteria.where("nbParts").is(0),
                Criteria.where("nbParts").is(null)
        );

        mongoTemplate.updateMulti(
                new Query(priceZeroCriteria),
                Update.update("nbParts", 122),
                LegoSet.class);
   }

Integration testing

Schema validation

Data Modeling

Optimization

Clean app arch

  • persistance (@Repository)
  • model (@Document)
  • api (@RestController)

Tools

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment