I am stuck with an issue and not sure how to proceed with it.
I have a DTO something like this :-
ORDER DTO:-
[
{
"ordNo": "77456",
"patients" :[ :- THIS DTO IS SHOTPATIENTDTO
{
"patientFirstName" : "Test",
"patientLastName" : "Dummy",
"patientDob" : "2018-01-04",
"patientUr" : "12345",
"patientId" : "1",
"batches" :[ //:------SHOTTEMPBACTH DTO
{
"batchId":"37", :- for each of the ID, I will set the BATCHDTO
"treatmentDateTime": "2017-12-06 17:55:50",
"status":"Submitted"
},
{
"batchId":"38",
"treatmentDateTime": "2017-12-06 17:55:50",
"Status":"On Hold"
}]
},
{
"patientFirstName" : "Second",
"patientLastName" : "Dummy",
"patientDob" : "2018-01-04",
"patientUr" : "542",
"patientId" : "1",
"batches" :[
{
"batchId":"39",
"treatmentDateTime": "2017-12-06 17:55:50",
"status":"Submitted"
},
{
"batchId":"40",
"treatmentDateTime": "2017-12-06 17:55:50",
"Status":"On Hold"
}]
}]
}]
I have an enitity which is ORDER having one to many relationship with BATCH TABLE.
Order which has a list of Batches(retrieve the batch using the batchId and set the object using the ORDER DTO) and there is another entity as SHOT_BATCH which conists of Batch + some additional attributes like patient details.
So while constructing my shotbatch entity for saving,
I am doing like this
[1]
for ( each of the order, get me the batches)
{
create an object of SHOTBATCH and set the properties
}
DAO.save(SHOTBATCH)
My question, I would like to set the patient name for each of the batches. How shall I iterate in order to get that ? In the above example, I would be
getting 4 batches(37-40) in the above loop[1]. so how can I determine which patient belongs to which batch so that I can set it in the SHOTBATCH.
Appreciate your help.
Please let me know if I got something wrong about your question. I understand that you want to build a collection and batch save it rather that calling DAO.save for every batchShot object. I would approach it in this way:
Lets say that we have the BatchShot object:
class ShotBatch {
private List<Shot> shots;
private String patientName;
public ShotBatch(final String patientName, final Shot[] shots) {
this.shots = Arrays.asList(shots);
this.patientName = patientName;
}
// getters setters
}
Then the create and save code would be:
List<ShotBatch> patientBatches = new ArrayList<>();
for (final Order order: orders) {
for (final Patient patient: order.getPatients()) {
// Assuming that patien has method getFullName that returns a String
// and getShots that returns an array of Shots
patientBatches.add(new ShotBatch(patient.getFullName(), patient.getShots()));
}
}
ShotBatchDao.saveAll(patientBatches);
Related
I'm trying to get the order number where a transactionId is equal to another variable I have in my code. My tolls.booths collection looks like this
In my code,
def boothsException = booths.find([ "pings.loc.transactionId": tollEvent.id, "pings.loc.order":1] as BasicDBObject).iterator()
println boothsException
I am getting boothsException = DBCursor{collection=DBCollection{database=DB{name='tolls'}
I would like to essentially say get where transactionId = 410527376 and give me that order number in boothsException (5233423).
This is using MongoDB Java Driver v3.12.2.
The code extracts the value from the returned cursor. I am using newer APIs, so you will find some differences in class names.
int transId = 410527376; // same as tollEvent.id
MongoCursor<Document> cursor = collection
.find(eq("pings.loc.transactionId", transId))
.projection(fields(elemMatch("pings.loc.transactionId"), excludeId()))
.iterator();
while (cursor.hasNext()) {
Document doc = cursor.next();
List<Document> pings = doc.get("pings", List.class);
Integer order = pings.get(0).getEmbedded(Arrays.asList("loc","order"), Double.class).intValue();
System.out.println(order.toString()); // prints 5233423
}
NOTES:
The query with projection gets the following one sub-document from the pings array:
"pings" : [
{
"upvote" : 575,
"loc" : {
"type" : "2dsphere",
"coordinates" : [ .... ],
"transactionId" : 410527376,
"order" : 5233423
},
...
}
]
The remaining code with looping the cursor is to extract the order value from it.
The following are the imports used with the find method's filter and projection:
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Projections.*;
I'm facing the problem for pagination data. Page data is getting calculated using the outer array dXPRecommendationResponses where I want it should be calculated through the nested array recommendations. I've mentioned the response data in result section.
I tried to change the page data calculation but it is getting calculated using the the data which we are passing in PageImpl() constructor.
I've used this approach to paginate the data which we are getting from third party API.
But it is getting calculated using the dxpRecommendationslist.
#This is the code through I need to generate the response
List<DXPRecommendationResponse> dxpRecommendationslist = new ArrayList<>();
List<DXPActivity> dxpActivities = getThirdResponse(pageable, correlationId,
dxpRecommendationslist, reservationGuestId, reservationId, nbxRecommendationRequest);
return new PageImpl<>(dxpRecommendationslist, pageable, dxpActivities.size());
#This method is used to get data from third party
public List<DXPActivity> getThirdResponse(final Pageable pageable, final String correlationId,
List<DXPRecommendationResponse> list, String reservationGuestId, String reservationId,
NBXRecommendationRequest nbxRecommendationRequest) {
List<DXPActivity> dxpActivities = new ArrayList<>();
NBXRecommendationResponse nbxRecommendationResponse = vVNBXRecommendationService
.getCalendarRecommendation(nbxRecommendationRequest, correlationId);
if (nbxRecommendationResponse != null) {
DXPRecommendationResponse dxpRecommendationResponse = new DXPRecommendationResponse();
dxpRecommendationResponse.setReservationGuestId(reservationGuestId);
dxpRecommendationResponse.setReservationNumber(reservationId);
dxpRecommendationResponse.setRecommendationType("CalendarType");
dxpRecommendationResponse.setDateTime(new Date());
populateActivities(dxpActivities, nbxRecommendationResponse);
List<DXPActivity> filteredList;
if (!CollectionUtils.isEmpty(dxpActivities)
&& dxpActivities.size() >= (pageable.getPageSize() * pageable.getPageNumber())) {
filteredList = Lists.partition(dxpActivities, pageable.getPageSize()).get(pageable.getPageNumber());
} else {
filteredList = new ArrayList<DXPActivity>();
}
dxpRecommendationResponse.setRecommendations(filteredList);
list.add(dxpRecommendationResponse);
}
return dxpActivities;
}
#This method is used to populate data
private void populateActivities(List<DXPActivity> dxpActivities,
NBXRecommendationResponse nbxRecommendationResponse) {
for (Activity activity :nbxRecommendationResponse.getCalendarRecommendation().getRecommendations().getActivities()) {
DXPActivity dxpActivity = new DXPActivity();
orikaMapper.map(activity, dxpActivity);
dxpActivities.add(dxpActivity);
}
}
The response data:
{
"_embedded": {
"dXPRecommendationResponses": [
{
"recommendationType": "CalendarType",
"reservationGuestId": "525dab66-1492-4908-a3bf-b5de558368e5",
"reservationNumber": "3a39f9ad-7e34-4bdb-91eb-b907fd6986c7",
"dateTime": "2019-08-19T14:38:18.413",
"recommendations": [
{
"productCode": "BIKE2006111000",
"activityName": "Bimini Bike Tour",
"recommendationId": "1565948843492_410387839_BIKE2006111000_cal",
"categoryCode": "DARING",
"activityStartTime": "2020-06-11T08:30:00.000",
"activityEndTime": "2020-06-11T11:30:00.000",
"activityDescription": "Bimini Bike Tour",
"sequence": 34.0,
"packageId": 103806,
"sourceId": "BIMINI BIKE",
"levelOfActivity": "EASY"
},
{
"productCode": "CUL2006110900",
"activityName": "Bimini Culinary Tour",
"recommendationId":"156594884349,
"categoryCode": "CULTURED",
"activityStartTime": "2020-06-11T07:30:00.000",
"activityEndTime": "2020-06-11T12:30:00.000",
"activityDescription": "Bimini Culinary Tour",
"sequence": 29.0,
"packageId": 103940,
"sourceId": "BIMINI CUL",
"levelOfActivity": "MODERATE"
}
]
}
]
},
"page": {
"size": 10,
"totalElements": 1,
"totalPages": 1,
"number": 0
}
}
The problem here is implementation of PageImpl constructor and how the resulting total is being computed here. Below is code taken from the constructor:
this.total = pageable.toOptional().filter(it -> !content.isEmpty())//
.filter(it -> it.getOffset() + it.getPageSize() > total)//
.map(it -> it.getOffset() + content.size())//
.orElse(total);
The important line here is second one, as described in doc comment, it is insurance against inconsistensies. It checks if you are on the last page and if so, it will use third line to compute resulting total. Therefore totally omitting total given by you. If you want to rewrite this behavior you should implement your Page which uses only given total.
BUT, I don't think it is semantically correct. You are mixing together things which probably should not be mixed (page object of one type, but the actual pagination done on another). The list given as pageable always has one element and you are paging subelements which does not seem right, is there even need to paginate the subelements?
One of the possible resolutions would be to make pageable only subelements by specifying Page<DXPActivity> recommendations member directly inside DXPRecommendationResponse and returning non-pageable DXPRecommendationResponse. But again, it seems a bit off. It really depens on what you are trying to build here and what is the logic behind that.
I have a collection like the one below, I want to get the _id value from the offerObject subdocument, I am using mongoTemplate in the Spring framework.
{
"_id" : ObjectId("543be5f3cbdf2e1eb442cb81"),`
"_class" : "com.mongodb.BasicDBObject",
"offerObject" : {
"_id" : ObjectId("543bbb7ecbdf85c6ceb44f33"),
"type" : "offer"
}
}
Can somebody help me with this?
I haven't used MongoTemplate, but based off previous experience doing java programming with Mongo, it would look something like this:
// Pull a document from the Collection
MongoDummyObject mdo = yourTemplate.findOne(query, MongDummyObject.class);
// Get the offer Object from the MongoDummyObject
OfferObject offerObject = mdo.getOfferObject();
// Pull the id from the offer object
String id = offerObject.getId();
I have the following code, :
CommandResult cr = db.doEval("db." + collectionName + ".aggregate("
+ query + ")");
Command result is giving in batches, where I need to get in single value.
Batch Result:{ "serverUsed" : "/servername" , "retval" : { **"_firstBatch**" : [ { "visitor_localdate" : 1367260200} , { "visitor_localdate"
Expected Result:
{ "serverUsed" : "/servername" , "retval" : { "**result**" : [ { "visitor_localdate" : 1367260200} , { "visitor_localdate"
The Mongo DB we are using is 2.6.4 with 64 bit.
Can any one help with this?. I am guessing there is some Configuration issue.
Your doing this all wrong. You don't need to jump through hoops like this just to get a dynamic collection name. Just use this syntax instead:
var collectionName = "collection";
var cursor = db[collectionName].aggregate( pipeline )
Where pipeline also is just the array of pipeline stage documents, ie:
var pipeline = [{ "$match": { } }, { "$group": { "_id": "$field" } }];
At any rate the .aggregate() method returns a cursor, you can iterate the results with standard methods:
while ( cursor.hasNext() ) {
var doc = cursor.next();
// do something with doc
}
But you are actually doing this in Java and not JavaScript, so from the base driver with a connection on object db you just do this:
DBObject match = new BasicDBObject("$match", new BasicDBObject());
DBObject group = new BasicDBObject("$group", new BasicDBObject());
List pipeline = new ArrayList();
pipeline.add(match);
pipeline.add(group);
AggregationOutput output = db.getCollection("collectionName").aggregate(pipeline);
The pipeline is basically a list interface of DBObject information where you construct the BSON documents representing the operations required.
The result here is of AggregationOutput, but cursor like results are obtainable by additionally supplying AggregationOptions as an additional option to pipeline
There was something related to bacth added in mongodb 2.6, more details here: http://docs.mongodb.org/manual/reference/method/db.collection.aggregate/#example-aggregate-method-initial-batch-size
From the link
db.orders.aggregate(
[
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 2 }
],
{
cursor: { batchSize: 0 }
}
)
You might be having a cursor batch in your aggregate query
The answer from Neil Lunn is not wrong but I want to add that the result you were expecting is a result for mongodb versions earlier than v2.6.
Before v2.6, the aggregate function returned just one document containing a result field, which holds an array of documents returned by the pipeline, and an ok field, which holds the value 1, indicating success.
However, from mongodb v2.6 on, the aggregate function returns a cursor (if $out option was not used).
See examples in mongodb v2.6 documentation and compare how it worked before v2.6 (i.e. in v2.4):
I'm new at MongoDB. I have a "Report" dropdown in my interface and depending of the report selected a query is executed.
On the other hand I have a "reports" collection for example like this:
{
_id : 1,
reportName : "Count users",
queryScript : "db.users.count()"
}, {
_id : 2,
reportName : "Find user names",
queryScript : "db.users.find( {}, { name : true } )"
}, etc
We have to do something similar to this pseudo code:
Report report = db.reports.find({ id : 1 });
String result = mongoClient.execute ( report.getQueryScript );
Is it possible? Can you give a hand on this?
You can use server side javascript:
db.system.js.save({
_id : "countUsers" ,
value : function (){ return db.test.count(); }
});
and so on. But keep the _id as a normal name of the function, because you will later evoke it by _id. Then you do
db.loadServerScripts();
and after this you can execute your query:
countUsers();