RxJava Retrofit make multiple requests for id - java

I have JSON
{ "cameras" : [
{
"archives" : [
{
"accessPoint" : "xxxx",
"default" : true,
"isEmbedded" : false,
"storage" : "xxxx",
"storageDisplayName" : "xxxx"
}
],
"audioStreams" : [],
"comment" : "",
"detectors" : [
{
"accessPoint" : "xxxx",
"displayName" : "",
"events" : [ "SceneChangeDetected" ],
"isActivated" : true,
"parentDetector" : "",
"type" : "xxxx"
},
{
"accessPoint" : "xxxx",
"displayName" : "",
"events" : [ "xxx" ],
"isActivated" : true,
"parentDetector" : "",
"type" : "xxxx"
}
],
"displayId" : "1",
"displayName" : "xxx",
"ipAddress" : "0.0.0.0",
"isActivated" : true,
"latitude" : "xxxx",
"longitude" : "xxx",
"model" : "Virtual",
"offlineDetectors" : [],
"ptzs" : [],
"textSources" : [],
"vendor" : "AxxonSoft",
"videoStreams" : [
{
"accessPoint" : "xxx
}
]
}, "archives" : [
POJO
public class allCameras {
#SerializedName("cameras")
#Expose
private ArrayList camera;
public ArrayList<Camera> getCameras() {
return camera;
}
public void setCameras(ArrayList<Camera> cameras) {
this.camera = cameras;
}
public class Camera {
#SerializedName("archives")
#Expose
private ArrayList archives;
#SerializedName("displayName")
#Expose
private String displayName;
public ArrayList<Archive> getArchives() {
return archives;
}
public void setArchives(ArrayList<Archive> archives) {
this.archives = archives;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
And I have a code in which I get the List with the help of RXJAVA
Next, I wanted to combine two requests and pass the execution result (id) from one to the other
But I am faced with a problem: in order for this to work, I must receive one Camera object at a time and pass its ID to another function
But I can only get a ArrayList
Help, please, what to do?

Related

Spring Data REST - Unrecognized field "_embedded" by consuming list of entities, Java HATEOAS

I am trying to consume a list of entities from the following REST HAL response:
{
"_embedded" : {
"posts" : [ {
"branch" : 1,
"article" : "aaaaaaa",
"featuredImage" : "aaaaaaa",
"authorId" : 1,
"datePublished" : "2020-05-05T09:11:13.336+0000",
"commentsEnabled" : true,
"enabled" : false,
"views" : 0,
"snippetTitle" : null,
"snippetDescription" : null,
"comments" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8081/posts/1"
},
"post" : {
"href" : "http://localhost:8081/posts/1"
},
"categories" : {
"href" : "http://localhost:8081/posts/1/categories"
}
}
}, {
"branch" : 1,
"article" : "aaaaaaa",
"featuredImage" : "aaaaaaa",
"authorId" : 1,
"datePublished" : "2020-05-05T10:45:15.999+0000",
"commentsEnabled" : true,
"enabled" : false,
"views" : 0,
"snippetTitle" : null,
"snippetDescription" : null,
"comments" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8081/posts/3"
},
"post" : {
"href" : "http://localhost:8081/posts/3"
},
"categories" : {
"href" : "http://localhost:8081/posts/3/categories"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8081/posts/search/byAuthorId?authorId=1&page=0&size=10"
}
},
"page" : {
"size" : 10,
"totalElements" : 3,
"totalPages" : 1,
"number" : 0
}
}
I would like to map these entities to this class:
#Setter
#Getter
#AllArgsConstructor
public class Post {
private int id;
private int branch;
private String article;
private Date datePublished;
private String featuredImage;
private Boolean commentsEnabled;
private Boolean enabled;
private int views;
private String snippetTitle;
private String snippetDescription;
}
However, I keep getting the error:
Unrecognized field "_embedded" (class
org.springframework.hateoas.PagedModel), not marked as ignorable (3
known properties: "links", "page", "content"])
With this code:
ObjectMapper mapper = new ObjectMapper();
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
messageConverter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
messageConverter.setObjectMapper(mapper);
ResponseEntity<PagedModel<Post>> responseEntity =
new RestTemplate(Arrays.asList(messageConverter)).exchange(uri, HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference<PagedModel<Post>>() {});
The versions are:
Jackson-databind version: 2.11.0
Spring-hateoas version: 1.0.5.RELEASE
Any help would be appreciated!
Response structure seems like PagedResources<T> type.
Use org.springframework.hateoas.PagedResources in ParameterizedTypeReference
ResponseEntity<PagedResources<Post>> responseEntity =
new RestTemplate(Arrays.asList(messageConverter)).exchange(uri, HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference<PagedResources<Post>>() {});

Passing array as parameter in filter function with spring-data-mongodb

I have this collection of documents:
[
{
"name": "name1",
"data": [
{
"numbers": ["1","2","3"]
}
]
},
{
"name": "name2",
"data": [
{
"numbers": ["2","5","3"]
}
]
},
{
"name": "name3",
"data": [
{
"numbers": ["1","5","2"]
}
]
},
{
"name": "name4",
"data": [
{
"numbers": ["1","4","3"]
}
]
},
{
"name": "name5",
"data": [
{
"numbers": ["1","2"]
}
]
}
]
I want to get all documents of this collection when an array passed as a parameter is a subset of data.numbers.
This is the aggregation that I'm using.
db.testing.aggregate(
[
{ "$match" : { "data.numbers" : { "$exists" : true } } },
{ "$project" : { "is_subset" : { "$filter" : { "input" : "$data", "as" : "d", "cond" : { "$setIsSubset" :[ ["1"],"$$d.numbers"] } } } } },
{ "$match" : { "is_subset.0" : { "$exists" : true } } }]
);
I'm trying to reproduce the above aggregation in Spring Data MongoDB.
How to pass an array as parameter in $filter and $setIsSubset functions?
operations.aggregate(
newAggregation(Testing.class,
match(where("data.numbers").exists(true)),
project().and(
filter("data")
.as("d")
.by(???))
.as("is_subset"),
match(where("is_subset.0").exists(true))
), Testing.class);
I solve my issue.
operations.aggregate(
newAggregation(Testing.class,
match(where("data.numbers").exists(true)),
project("id", "name").and(
filter("data")
.as("d")
.by(context -> new Document("$setIsSubset", Arrays.asList(numbers, "$$d.numbers"))))
.as("is_subset"),
match(where("is_subset.0").exists(true))
), Testing.class);
I created a Document with the content that I needed in the $filter condition.
new Document("$setIsSubset", Arrays.asList(numbers, "$$d.numbers"))

Getting the total count of array list elements from all documents of a collection

enter image description hereI am trying to get the activity of my users in which I am trying to get the total followers and following of all users in my userinfo table.
I am using the below command line query to get that which is working fine and I am getting the total count.
db.userinfo.aggregate([
{ "$group": {
"_id": null,
"followersCount": {
"$sum": {
"$size": { $ifNull: [ "$followers", [] ] }
}
},
"followingCount": {
"$sum": {
"$size": { $ifNull: [ "$i_am_following", [] ] }
}
}
}}
])
But I am unable to replicate this using java programming. Can we write this query in java using BasicDBObjects or Is there any other way to do this?
Here is the sample data for a single user.
db.userinfo.insert (
{
"username" : "user1",
"useremail" : "user1#gmail.com",
"password" : "password",
"firstname" : "firstname",
"lastname" : "lastname",
"dob" : "24-05-1992",
"followers" : [
{
"user" : "user2",
"from_date" : "2016-12-15 09:59:04"
},
{
"user" : "user3",
"from_date" : "2016-12-15 08:59:04"
}
],
"i_am_following" : [
{
"user" : "user2",
"from_date" : "2016-12-15 08:59:04"
},
{
"user" : "user3",
"from_date" : "2016-12-15 09:59:04"
}
]
})
You can try something like this.
import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;
import static com.mongodb.client.model.Projections.computed;
import static java.util.Arrays.asList;
import static java.util.Collections.EMPTY_LIST;
Bson group = group(null,
sum("followersCount", computed("$size",
computed("$ifNull",
asList("$followers", EMPTY_LIST)))),
sum("followingCount", computed("$size",
computed("$ifNull",
asList("$i_am_following", EMPTY_LIST))))
);
AggregateIterable <Document> output = userinfo.aggregate(asList(group));

Subaggregation results are not properly showing

I am using Java Springdata elasticsearch and I want to use sub-aggregation and model the following query.
{
"from" : 0,
"size" : 10,
"sort" : [ {
"_score" : {
"order" : "desc"
}
} ],
"aggregations" : {
"parentAgg" : {
"terms" : {
"field" : "parentField",
"size" : 0
},
"aggregations" : {
"childAgg" : {
"terms" : {
"field" : "childField"
}
}
}
}
}
}
Currently I have used subaggregation (i.e. Aggregation.subAggregation(subAggName)) however output I get is -
"aggregations": [
{
"field": "parentAgg",
"values": [
{
"term": "val1",
"docCount": 2
},
{
"term": "val2",
"docCount": 2
},
{
"term": "val3",
"docCount": 1
}
]
}
]
Relavent Java Code -
for (Object aggregationField : request.getAggregationFields()) {
TermsBuilder termBuilder = AggregationBuilders.terms(aggregationField.toString())
.field(aggregationField.toString()).size(0);
if(aggregationField.toString().equals("parentField"))
{
TermsBuilder childBuilder = AggregationBuilders.terms("childAgg").field("childField").size(0);
termBuilder.subAggregation(childBuilder);
}
nativeSearchQueryBuilder.addAggregation(termBuilder);
}
Can you please let me know what I am missing?

$project is not working in mongo query [duplicate]

I need to export customer records from database of mongoDB. Exported customer records should not have duplicated values. "firstName+lastName+code" is the key to DE-duped the record and If there are two records present in database with same key then I need to give preference to source field with value other than email.
customer (id,firstName,lastName,code,source) collection is this.
If there are record 3 records with same unique key and 3 different sources then i need to choose only one record between 2 sources(TV,internet){or if there are n number of sources i need the one record only}not with the 'email'(as email will be choosen when only one record is present with the unique key and source is email)
query using:
db.customer.aggregate([
{
"$match": {
"active": true,
"dealerCode": { "$in": ["111391"] },
"source": { "$in": ["email", "TV", "internet"] }
}
},
{
$group: {
"_id": {
"firstName": "$personalInfo.firstName",
"lastName": "$personalInfo.lastName",
"code": "$vehicle.code"
},
"source": {
$addToSet: { "source": "$source" }
}
}
},
{
$redact:
{
$cond: [
{ $eq: [{ $ifNull: ["$source", "other"] }, "email"] },
"$$PRUNE",
"$$DESCEND"
]
}
},
{
$project:
{
"source":
{
$map:
{
"input": {
$cond: [
{ $eq: [{ $size: "$source" }, 0] },
[{ "source": "email" }],
"$source"
]
},
"as": "inp",
"in": "$$inp.source"
}
},
"record": { "_id": 1 }
}
}
])
sample output:
{ "_id" : { "firstName" : "sGI6YaJ36WRfI4xuJQzI7A==", "lastName" : "99eQ7i+uTOqO8X+IPW+NOA==", "code" : "1GTHK23688F113955" }, "source" : ["internet"] }
{ "_id" : { "firstName" : "WYDROTF/9vs9O7XhdIKd5Q==", "lastName" : "BM18Uq/ltcbdx0UJOXh7Sw==", "code" : "1G4GE5GV5AF180133" }, "source" : ["internet"] }
{ "_id" : { "firstName" : "id+U2gYNHQaNQRWXpe34MA==", "lastName" : "AIs1G33QnH9RB0nupJEvjw==", "code" : "1G4GE5EV0AF177966" }, "source" : ["internet"] }
{ "_id" : { "firstName" : "qhreJVuUA5l8lnBPVhMAdw==", "lastName" : "petb0Qx3YPfebSioY0wL9w==", "code" : "1G1AL55F277253143" }, "source" : ["TV"] }
{ "_id" : { "firstName" : "qhreJVuUA5l8lnBPVhMAdw==", "lastName" : "6LB/NmhbfqTagbOnHFGoog==", "code" : "1GCVKREC0EZ168134" }, "source" : ["TV", "internet"] }
This is a problem with this query please suggest :(
Your code doesn't work, because $cond is not an accumulator operator. Only these accumulator operators, can be used in a $group stage.
Assuming your records contain not more than two possible values of source as you mention in your question, you could add a conditional $project stage and modify the $group stage as,
Code:
db.customer.aggregate([
{
$group: {
"_id": {
"id": "$id",
"firstName": "$firstName",
"lastName": "$lastName",
"code": "$code"
},
"sourceA": { $first: "$source" },
"sourceB": { $last: "$source" }
}
},
{
$project: {
"source": {
$cond: [
{ $eq: ["$sourceA", "email"] },
"$sourceB",
"$sourceA"
]
}
}
}
])
In case there can be more that two possible values for source, then you could do the following:
Group by the id, firstName, lastName and code. Accumulate
the unique values of source, using the $addToSet operator.
Use $redact to keep only the values other than email.
Project the required fields, if the source array is empty(all the elements have been removed), add a
value email to it.
Unwind the source field to list it as a field and not an array.
(optional)
Code:
db.customer.aggregate([
{
$group: {
"_id": {
"id": "$id",
"firstName": "$firstName",
"lastName": "$lastName",
"code": "$code"
},
"sourceArr": { $addToSet: { "source": "$source" } }
}
},
{
$redact: {
$cond: [
{ $eq: [{ $ifNull: ["$source", "other"] }, "email"] },
"$$PRUNE",
"$$DESCEND"
]
}
},
{
$project: {
"source": {
$map: {
"input":
{
$cond: [
{ $eq: [{ $size: "$sourceArr" }, 0] },
[{ "source": "item" }],
"$sourceArr"]
},
"as": "inp",
"in": "$$inp.source"
}
}
}
}
])

Categories

Resources