MongoDb spring boot jpa #Aggregation _id deserialization problem - spring

Below aggregation always produces _id that looks like this.
"_id": { "timestamp": 1675104059, "date": "2023-01-30T18:40:59.000+00:00" },
and I need like this :
"_id": "63d80f2ddf20b2268a986dbf"
#Aggregation(pipeline = {"{'$match': {'userId': '?0'}}","{'$project': {'allEventsOfUser': 1}}","{'$unwind': {'path': '$allEventsOfUser'}}","{'$match': {'allEventsOfUser.date': {'$gte': ?1, '$lte': ?2}}}"}) List<?> findByUserIdAndDateRange(String name, Date dateStart, Date dateEnd);
I do not understand why the aggregation produces different result. I have tried all variants of JsonIgnore it does nothing when added to the field, nor does adding to the setter or getter. Can someone please help me, its screwing up my whole update flow, i need actual id not some funky useless object in my case.
public class EventItem { #Id public String _id;
it hjas something to do with aggregation but im new to mongodb and i have no idea how to stop this. Much thnx for anyone who helps!

You need to specify the id type:
#Field(targetType = FieldType.STRING)
public String id;
I do NOT know why this breaks with #Aggregation annotation, there were NO problems with same api with different query like find all.

Related

Update by query multiple fields using Spring Data Elasticsearch?

I want to update all the documents that have for exemple the same name. I've seen in the elasticsearch documentation that I can use _update_by_query. So I tried to implement it in my repository like this:
#Query("{\"script\": { \"inline\": \"ctx._source.name = ?1\"; \"ctx._source.username = ?2\"; \"ctx._source.avatar = ?3\", \"lang\": \"painless\" }, \"query\": { \"match\": { \"name\" : \"?1\" }}")
List<User> update(String name, String username, String avatar);
But I get the following error:
nested exception is ElasticsearchStatusException[Elasticsearch exception [type=parsing_exception, reason=[script] query does not support [inline]]]
at org.springframework.kafka.listener.SeekUtils.seekOrRecover(SeekUtils.java:157) ~[spring-kafka-2.5.0.RELEASE.jar:2.5.0.RELEASE]
Edit 26.06.2020:
This answer is not correct, I added a correct on.
Old incorrect answer:
Seems strange to me, that this error comes from org.springframework.kafka.listener.SeekUtils.
To update using a script, you can use the update(UpdateQuery updateQuery, IndexCoordinates index) of a ElasticsearchOperations instance.
To have this in your Repository, you will need to create a repository cusomization like it is described here. In the implementation, autowire a ElasticsearchOperations instance. In this custom repository interface, you define the method
List<User> update(String name, String username, String avatar);
In the implementation, build up a UpdateQuery object with the script and the other information and pass this to the ElasticsearchOperations instance.
After checking the code of Spring Data Elasticsearch, I need to withdraw what I wrote in the first answer:
Currently Spring Data Elasticsearch does not support update by query. It is only possible to update entities with a know id either in a single operation or in a batch update.
I created an issue in Jira to add support for that.

spring-data-mongodb using the fieldName instead of _id

I have a Pojo with an attribute as
Class A{
#Id
#Field("item_id")
private String itemId;
}
When i try to update a document in MongoDB collection based on the itemId as below, it worked well and able to see from mongo ops logs that the query was transformed as "_id in itemIds "
Query query = new Query(Criteria.where("itemId").in(itemIds));
Update update = new Update();
update.set("field2", "abd");
mongoTemplate.updateMulti(query, update, A.class)
When i upgraded to spring-data-mongodb-2.1.5.RELEASE, the query i saw in the mongo logs was "item_id in itemIds". Since item_id is not a field and no index for that field in the collection, the query took forever to complete.
Any help to understand why the spring-data library is building the query as _id in older version and using the field as it is in newer version?
After a 2 minute search on the Spring documentation (https://docs.spring.io/spring-data/mongodb/docs/1.3.3.RELEASE/reference/html/mapping-chapter.html):
The following outlines what field will be mapped to the '_id' document field:
A field annotated with #Id (org.springframework.data.annotation.Id) will be mapped to the '_id' field.
A field without an annotation but named id will be mapped to the '_id' field.
Did you try that already?

How to set OpType on IndexQuery in Spring Data Elasticsearch

Assume spring-boot-starter-data-elasticsearch version 2.1.0.RC1.
Take the following, simple implementation for indexing an entity:
IndexQuery indexQuery = new IndexQueryBuilder().withId(entity.getId()).withObject(entity).build();
String id = elasticsearchTemplate.index(indexQuery);
How do I set the OpType.CREATE on this operation, so that I can assure only documents get indexed which don't already exist?
The equivalent REST API request would look like the following:
POST /{index}/{entity id}?op_type=create
{
"id" : "{entity id}",
"attribute" : "value"
}
This is not supported at the moment by Spring Data ES.
There's a open issue that reports exactly that feature, you might want to check it out: https://jira.spring.io/browse/DATAES-247

Spring Elastic Search Custom Field names

I am new to Elastic Search and I am trying to implement it using Spring-data-elasticsearch.
I have fields with names such as "Transportation", "Telephone_Number" in our elastic search documents.
When I try to map my #Domain object fields with those, I don't get any data for those as I couldn't successfully map those fields.
Tried to use #Field, was disappointed as it didn't have 'name' property in it to map with custom field name.
Tried different variations of a GETTER function, none of those seem to be mapping to those fields.
I started wondering if there's something I'm missing here.
How does a domain object field look like which should map to a filed called something like "Transportation" ?
Any help appreciated
You can use custom name. Spring Data ES use Jackson. So, you can use #JsonProperty("your_custom_name") to enable custom name in ES Mapping
for example:
#Document(indexName = "your_index_name", type = "your_type_name")
public class YourEntity {
....
#JsonProperty("my_transportation")
#Field(type = FieldType.String, searchAnalyzer = "standard", indexAnalyzer = "standard", store = true) // just for example
private String myTransportation;
....
}
Note: I'm sorry anyway, my english is bad.. :D

Spring Data Mongo nested id won't work

Does Spring Data treats mongo nested "id" attributes differently? I explain my problem: I have collection matches with the following structure
"teams": [
{
"id" : "5601",
"name" : "FC Basel"
},
... // more
]
When I want to retrieve all the matches which has team id 5601 I execute the following query
db.matches.find({ "teams.id" : "5601"})
Which works perfectly and returns some objects.
When I make a method
public List<MatchMongo> findByTeams_id(String id);
on my MatchRepository interface I get 0 results back while there are.
Logs shows
Created query Query: { "teams.id" : "5601"}, Fields: null, Sort: null
find using query: { "teams.id" : "5601"} fields: null for class: class
MatchMongo in collection: matches
So the query he makes seems to be the right one... :S
Trying with other fields (referee.name for ex.) works.
I even tried with the #Query annotation, but can't get it to work
Is there another solution? Is this a bug or am I doing something wrong?
Oh found the solution:
MatchMongo had List<TeamMongo> teams; on whereI had
#Id
private String id;
#Field(value = "id")
private String teamIdAttr;
So the method should be called
public List<MatchMongo> findByTeams_teamIdAttr(String id);
Never thought the method name should reflect objects attributes instead of collection structure
Thanks #martin-baumgartner your comment helped to solve this :)

Resources