Field exclusion or inclusion in nested document in MongoDB Spring Boot - spring

I want to exclude or include only some fields in nested document from findAll request. How can I achieve this ?
#Document()
class Post {
String id;
String title;
String description;
#DocumentReference
User userId;
}
#Document()
class User {
String id;
String name;
String email;
String password;
....
}
I want a response like this
[{
"id": 1,
"title": "delectus aut autem",
"description" : "delectus aut autem ..",
"userId" : { "id" : 1, "name" : "Nikhil" }
},
...
]
Using fildAll it gives complate user document

Related

to serialize a list of objects as a list of strings by suppressing irrelevant tags in the object

I am using Spring Boot to create a Rest Service to return some Json. Below is the model in question, in which I am suppressing the id from being serialized to Json with #JsonIgnore
//imports
#Entity
#Table(name="tags")
public class Tag {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="post_id")
#JsonBackReference
private Post post;
#Column(name="tag")
private String tag;
//....
#JsonIgnore
public int getId() {
return id;
}
#JsonSetter
public void setId(int id) {
this.id = id;
}
//...
}
But I would also like to suppress the "tag" tag. That is, I'd like the output to look like a String array rather than array of Javascript objects containing a string.
The current output is:
{
"id": 1,
"title": "welcome to the blog",
"body": "Lorem, ipsum...",
"tags" : [
{"tag" : "webdev"},
{"tag" : "coding"},
{"tag" : "news"}
]
}
But I would like to get the output like:
{
"id": 1,
"title": "welcome to the blog",
"body": "Lorem, ipsum...",
"tags": [
"webdev",
"coding",
"news"
]
}
Can this be done with an annotation of some sort?

How to fix update process in Spring Boot (One-to-Many , One-to-One) via Postman?

I have a problem about updating the movie.
I wrote a function that is named for "update" in MovieService.
Here is that function which is shown below.
public void update(Long id,Movie movie) {
boolean isUpdatingEmployee = (movie.getId() == id);
if (isUpdatingEmployee) {
Movie existingMovie = movieRepository.findById(movie.getId()).get();
existingMovie.setId(id);
existingMovie.setName(movie.getName());
existingMovie.setRating(movie.getRating());
existingMovie.setDirector(movie.getDirector());
existingMovie.setGenres(movie.getGenres());
existingMovie.setCreatedAt(movie.getCreatedAt());
movieRepository.save(existingMovie);
}
}
When ı try to update a movie after saving it, I got this kind of JSON result and that's why the update process cannot be done.
http://localhost:8082/api/v1/movie/update/1
Body Request
{
"name": "MovieC",
"genres": [
{
"name" : "Adventure"
},
{
"name" : "Action"
}
],
"createdAt": "2021-04-28",
"rating" : 9,
"director" : {
"name" : "Director 2"
}
}
The result of JSON after updating the process.
{
"id": null,
"name": "MovieC",
"genres": [
{
"id": null,
"name": "Action"
},
{
"id": null,
"name": "Adventure"
}
],
"rating": 9.0,
"createdAt": "2021-04-28",
"director": {
"id": null,
"name": "Director 2"
}
}
Here is my Movie entity which is shown below.
#Entity
#Getter
#Setter
#ToString
#AllArgsConstructor
#NoArgsConstructor
public class Movie implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#JsonManagedReference
#OneToMany(mappedBy="movie",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
private Set<Genre> genres;
private Double rating;
private LocalDate createdAt;
#ManyToOne(cascade=CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn
private Director director;
}
Here is my Director entity which is shown below.
#Entity
#Getter
#Setter
#ToString
#RequiredArgsConstructor
#NoArgsConstructor
#JsonIgnoreProperties({"movies"})
public class Director implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NonNull
private String name;
#OneToMany(mappedBy="director",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
private Set<Movie> movies;
}
Here is my Genre entity which is shown below.
#Entity
#Getter
#Setter
#ToString
#RequiredArgsConstructor
#NoArgsConstructor
#JsonIgnoreProperties({"movie"})
public class Genre implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NonNull
private String name;
#JsonBackReference
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn
private Movie movie;
}
Here is my sample project link : Project Link
How can I fix it?
As per your code, this is your request:
http://localhost:8082/api/v1/movie/update/1
{
"name": "MovieC",
"genres": [
{
"name" : "Adventure"
},
{
"name" : "Action"
}
],
"createdAt": "2021-04-28",
"rating" : 9,
"director" : {
"name" : "Director 2"
}
}
Now consider this snippet from your code:
public void update(Long id,Movie movie) {
boolean isUpdatingEmployee = (movie.getId() == id);
if (isUpdatingEmployee) {
...
Your id will be 1 as you've set this in your path variable.
However, movie.getId() will be null since I don't see it in your RequestBody.
And so:
isUpdatingEmployee = (movie.getId() == id)`
isUpdatingEmployee = ( null == 1)
isUpdatingEmployee = false
this will always give you false so I don't think this will enter in your update logic.
I think the problem because you are returning the same object movie you passed in the body of the post method in the controller - https://github.com/Rapter1990/springboothazelcast/blob/3157f354a628d418cccb99cfdbd188f594c24e9c/src/main/java/com/springboot/hazelcast/controller/MovieController.java#L64
You should rewrite it to something like this:
#PostMapping("/save")
public Movie saveMovie(#RequestBody Movie movie) throws ParseException {
LOG.info("MovieController | Saving Movie.");
return movieService.save(movie);
}
Here is the link to CRUDRepository javadocs:
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html#save-S-

Spring elasticsearch filter terms consume list

I have the following index and query
#Document(indexName="idx", type="worker")
public class Worker {
#Id
#Field(type = FieldType.Long)
private Long id;
#Field(type = FieldType.String)
private String firstName;
#Field(type = FieldType.String)
private String lastName;
--getter--setter
}
public interface WRepo extends ElasticsearchRepository<Worker, Long> {
#Query("{
"query": {"match": {"firstName": "?0"}},
"filter": {"terms" : {"id" : ***ids***}}
}")
Page<Worker> searchWorker(String firstName, List<Long> ids, Pageable pageable);
}
Number of ids is changable, when adding ids static like
{"id" : [101, 102, 103]}
it works as expected, my question is how can I pass id list from method signature like firstName field
{"firstName": "?0"}
I changed method body below
#Query("{
"query": {"match": {"firstName": "?0"}},
"filter": {"terms" : {"id" : [?1]}}
}")
Page<Worker> searchWorker(String firstName, String ids, Pageable pageable);
and make my request as:
repository.searchProduct("firstName", "101,102", pageable)

Exposing field of child object in Spring hateoas

I have two entities defined:
#Entity
public class VideoPost {
private #Id
#GeneratedValue(strategy= GenerationType.IDENTITY) Long id;
private String videoTitle;
private #ManyToOne #JoinColumn(name = "VideoPost_Id") User uploader;
private boolean isPublished = false;
//....
}
#Entity
public class User {
private #Id #GeneratedValue(strategy=GenerationType.IDENTITY) Long id;
private String userName;
private Date registrationDate;
#OneToMany(mappedBy = "uploader", cascade = CascadeType.ALL) private List<VideoPost> videoPosts;
//...
}
I have following JSON response to the call to /api/videoposts:
"_embedded" : {
"videoPosts" : [ {
"videoTitle" : "test video 1",
"uploadDate" : "2017-06-03T11:44:02.012+0000",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/videoPosts/1"
},
"videoPost" : {
"href" : "http://localhost:8080/api/videoPosts/1"
},
"uploader" : {
"href" : "http://localhost:8080/api/videoPosts/1/uploader"
}
}
} ]
I would like to expose the uploader name inside this response directly. I.e.
"uploader" : {
"userName": theName
"href" : "http://localhost:8080/api/videoPosts/1/uploader"
}
How could I achieve this?
You can check Projections where you can customize you objects the way you want whether you want to show the whole nested attributes or some of them or even hide these nested objects

spring data elasticsearch field mapping

I have a badly designed document structure:
{
"_index": "items",
"_type": "item",
"_id": "CD5D8F6516A88805FA826C10777B1750D9AAF5DA9CDD8E264757AB7EEC22B1EB",
"_score": 1,
"_source": {
"title": "Textverständnis 5",
"active": true,
"successorId": null,
"metadata": {
"Fach": "DE",
"Kompetenz": "Les",
"code": "C_SX_DE_Les_A0016_00149_V00",
...
}
}
}
I would like to retrieve the the title, Fach, and code from the above document.
#Document(indexName = "items", type = "item")
#Data
public class Item {
#Id
private String id;
private String title;
private Metadata metadata;
#Data
static class Metadata {
private String Fach;
private String code;
}
}
Retrieving the title, code are ok, but the Fach field returns null. Do you know how could I map this field? It seems the issue is with the upper case, but unfortunately I cannot change the document structure.
Could you help?
Thanks.
was solved using Jackson's #JsonProperty annotation like:
#Document(indexName = "items", type = "item")
#Data
public class Item {
#Id
private String id;
private String title;
private Metadata metadata;
#Data
static class Metadata {
#JsonProperty("Fach")
private String subject;
private String code;
}
}

Resources