Spring elasticsearch filter terms consume list - elasticsearch

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)

Related

Field exclusion or inclusion in nested document in MongoDB Spring Boot

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

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-

JPA Repository many to one

I have Student entity and Course entity. This is #ManyToOne relationship i.e. Student may attend only one course at a time, but courses may have multiple students.
#Entity
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String studentId;
private String firstName;
private String secondName;
#ManyToOne
#JoinColumn(name = "course_id")
//#JsonIgnore
private Course course;
#Entity
public class Course {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String courseName;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "course", orphanRemoval = true, targetEntity = Student.class)
private List<Student> students = new ArrayList<>();
I post my data with the following json:
{
"id": 1,
"courseName": "course134",
"students" : [
{
"id" : 1,
"studentId": "123",
"firstName": "John1",
"secondName": "Name1"
},
{
"id" : 2,
"studentId": "1234567",
"firstName": "John2",
"secondName": "Name2"
}
then, as I get courses I receive:
{
"id": 1,
"courseName": "course134",
"students": []
}
How to list Students attending specific course?
I made up a Query in StudentRepository
#Query("SELECT s from Student s where s.id = :courseName")
Optional<Student> getStudentByCourseName(String courseName);
Still not working.
this is my Repository code:
#Repository
public interface CourseRepository extends JpaRepository<Course, Long> {
Optional<Course> findCourseByCourseName(String courseName);
#Query("SELECT c.students FROM Course c WHERE c.courseName = :courseName")
Optional<Student> getStudentsByCourseName(String courseName);
}
this is my Service method
public Optional<Student> findStudentByCourse(String courseName){
return courseRepository.getStudentsByCourseName(courseName);
}
and finally my Controller:
#GetMapping("/student/course/{courseName}")
public ResponseEntity<Student> findCoursesWithStudentId(#PathVariable String courseName) {
Optional<Student> byCourseName = studentService.findStudentByCourse(courseName);
if (byCourseName.isPresent()) {
return ResponseEntity.ok(byCourseName.get());
} else {
return ResponseEntity.notFound().build();
}
}
You should query the Course table, not the Student table. Also, the query will return the list, not just one entity, so change your method's return type also...
#Query("SELECT c.students FROM Course c WHERE c.courseName = :courseName")
List<Student> getStudentsByCourseName(String courseName) {}
edit
You can always do it like so:
Excute the simple method:
Course findByCourseName(String courseName) {}
and then just get its Students by a simple:
course.getStudents();

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