everyone!
I would be very grateful for your help, I am a beginner in working with MongoDB.
I have 2 classes
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user")
public class User {
@Transient
public static final String USER_SEQUENCE = "user_sequence";
@Id
private Long id;
private String username;
private String password;
private Set<Role> roles = new HashSet<>();
@DBRef
private List<Article> articles = new ArrayList<>();
}
and
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "articles")
public class Article {
@Transient
public static final String ARTICLE_SEQUENCE = "article_sequence";
@Id
private Long id;
private String text;
private int like = 0;
@Setter(AccessLevel.NONE)
private Set<Long> likedBy = new HashSet<>();
@Setter(AccessLevel.NONE)
private Set<Long> dislikedBy = new HashSet<>();
@DBRef
private User user;
public Article(Long id, String text, User user) {
this.id = id;
this.text = text;
this.user = user;
}
}
I need to implement a method that will retrieve all articles by username
This is my implementation, but it doesn’t work(((
public interface ArticleRepository extends MongoRepository<Article, Long> {
List<Article> findAllByOrderByIdDesc();
@Aggregation(pipeline = {
"{$lookup: {from: 'users', localField: 'user', foreignField: '_id', as: 'user'}}",
"{$unwind: '$user'}",
"{$match: {'user.username': ?0}}"
})
List<Article> findAllByUserUsername(String username);
}
Help me understand how to do this, please
Of course, I can pull out the User by name and take the gender from it, but I think it’s not right.
public interface UserRepository extends MongoRepository<User, Long> {
Optional<User> findByUsername(String username);
}
2
Answers
On
$lookup
stage you’re trying to join onuser
field which is a DBRef in the articles collection and_id
field in the users collection. The issue is that DBRef is a complex object, and you cannot directly compare it with the_id
field.In MongoDB, a DBRef is a document that contains the following fields:
Your
User
field in theArticle
collection would look something like this:Thus, in your
$lookup
part, you should useuser.$id
as the localField instead ofuser
:You can fetch only the list of articles from the User repository as follows:
Keep your User class as is in your question.
Remove
@DBRef private User user;
from your Article class.User Repository
This will fetch only the list of articles through your User class.