spring data mongodb BulkOperations upsert not save the data to mongodb - spring

for (int i = 0; i < deviceDataList.size(); i++) {
updateList = new ArrayList<>();
deviceData = deviceDataList.get(i);
Query query = new Query();
query.addCriteria(new Criteria("seqId").is(deviceData.getDeviceCd()));
query.addCriteria(new Criteria("time").is(deviceData.getGpsAtMillis()));
Update update = new Update();
update.set("seqId", deviceData.getSeqId());
update.set("partId", deviceData.getPartId());
update.set("partName", deviceData.getPartName());
update.set("time", deviceData.getTime());
Pair<Query, Update> updatePair = Pair.of(query, update);
updateList.add(updatePair);
}
MongoTemplate mongoTemplate = null;
BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, collectionName);
operations.upsert(updateList);
BulkWriteResult writeResult = operations.execute();
result.setSuccess(writeResult.wasAcknowledged());
result.setResult(writeResult.getModifiedCount());
I write a code to insert data when data do not exist or update data when data exist, but I find when the update data is included, the updateList data does not save into the MongoDB, I did not know why, this confuse me.
I use MongoDB 3.4.12 and use the spring-data-MongoDB jar, I am not sure why this happens, and what I should do to solve this problem.

Related

Find/Remove in #DBref list items in MongoDB for Spring

What would be the best approach to find and update nested list items as #DBRef in MongoDB for Spring?
I have a AppliedApplication class:
#Document(collection = "applied_application")
public class AppliedApplication {
#Id
private String id;
#Field("program")
#DBRef
private List<Program> programList;
// getters and setters
}
With a Program class as #DBRef:
#Document(collection = "program")
public class Program {
#Id
private String id;
#Field("program_name")
private String programName;
// getters and setters
}
I'm looking for a way to find and update the nested list items using the following queries:
Query used for finding a Program object by It's Id from AppliedApplication collection:
Query query = new Query();
query.addCriteria(Criteria.where("id").is(applicationId)
.and("program.$id").is(new ObjectId(programId)));
Program program = mongoTemplate.findOne(query, Program.class);
Query used for removing list item from AppliedApplication:
Update update = new Update().pull("program", new BasicDBObject("program.$id", new ObjectId(programId)));
mongoTemplate.updateMulti(new Query(), update, AppliedApplication.class);
None of them are working and I'm completely clueless.
Find:
Use positional operator/$elemMatch for finding the matching Program DBRef in the AppliedApplication.
Using $positional projection
Query query = new Query();
query.addCriteria(Criteria.where("id").is(new ObjectId(applicationId)).and("program.$id").is(new ObjectId(programId)));
query.fields().position("program", 1);
AppliedApplication application = mongoTemplate.findOne(query, AppliedApplication.class);
Program program = application.getProgramList().get(0);
Using $elemMatch projection
Query query = new Query();
query.addCriteria(Criteria.where("id").is(new ObjectId(applicationId)));
query.fields().elemMatch("program", Criteria.where("$id").is(new ObjectId(programId)));
AppliedApplication application = mongoTemplate.findOne(query, AppliedApplication.class);
Program program = application.getProgramList().get(0);
Remove:
Use $pull to remove the DBRef from list of program DBref's.
Query query = Query.query(Criteria.where("$id").is(new ObjectId(programId)));
Update update = new Update().pull("program", query);
mongoTemplate.updateMulti(new Query(), update, AppliedApplication.class);
Add
Use $push to add new programs to the list.
Query query = new Query();
query.addCriteria(Criteria.where("id").is(new ObjectId(applicationId)));
Update update = new Update().push("program", new DBRef("program", new ObjectId(programId));
mongoTemplate.updateMulti(query, update, AppliedApplication.class);
First Query would run if you return the AppliedApplication
Query query = new Query();
query.addCriteria(Criteria.where("id")
.is(new ObjectId(applicationId))
.and("program.$id")
.is(new ObjectId(programId)));
AppliedApplication application = this.mongoOperations.findOne(query, AppliedApplication .class);
And then use application object to get the program.
For the second query you need to change ,
Update update = new Update().pull("program", new BasicDBObject("$id", new ObjectId(programId)));
mongoTemplate.updateMulti(new Query(), update, AppliedApplication.class);
Replace --> abc.$id to $id

how to write like facet.method=enum in query with spring solr

in solr query...
facet.method=enum
how spring data solr can do like above.
SimpleFacetQuery facetQuery = new SimpleFacetQuery(new Criteria(CrawlDocument.FIELD_CONTENT).contains(searchStr));
facetQuery.setFacetOptions(new FacetOptions().addFacetOnField(CrawlDocument.FIELD_CONTENT).setFacetLimit(20));
????
please give tips
It's depends on solrj-1.1.0 and spring-data-4.6.1.
#Test
public void testFacetMethodEnum() throws SolrServerException {
SimpleFacetQuery query = new SimpleFacetQuery();
query.addCriteria(new Criteria("coumn_name1").is("value1"));
query.addCriteria(new Criteria("coumn_name2").is("value2"));
query.addProjectionOnField("projection_1");
FacetOptions facetOptions = new FacetOptions("facet_field");
facetOptions.setFacetLimit(1000);
query.setFacetOptions(facetOptions);
QueryParsers queryParsers = new QueryParsers();
SolrQuery solrQuery = queryParsers.getForClass(query.getClass()).constructSolrQuery(query);
solrQuery.setParam(FacetParams.FACET_METHOD, FacetParams.FACET_METHOD_enum);
QueryResponse reponse = Your_SolrTemplate.getSolrOperations().getSolrServer().query(solrQuery);
assertNotNull(reponse);
}

saving & updating full json document with Spring data MongoTemplate

I'm using Spring data MongoTemplate to manage mongo operations. I'm trying to save & update json full documents (using String.class in java).
Example:
String content = "{MyId": "1","code":"UG","variables":[1,2,3,4,5]}";
String updatedContent = "{MyId": "1","code":"XX","variables":[6,7,8,9,10]}";
I know that I can update code & variables independently using:
Query query = new Query(where("MyId").is("1"));
Update update1 = new Update().set("code", "XX");
getMongoTemplate().upsert(query, update1, collectionId);
Update update2 = new Update().set("variables", "[6,7,8,9,10]");
getMongoTemplate().upsert(query, update2, collectionId);
But due to our application architecture, it could be more useful for us to directly replace the full object. As I know:
getMongoTemplate().save(content,collectionId)
getMongoTemplate().save(updatedContent,collectionId)
implements saveOrUpdate functionality, but this creates two objects, do not update anything.
I'm missing something? Any approach? Thanks
You can use Following Code :
Query query = new Query();
query.addCriteria(Criteria.where("MyId").is("1"));
Update update = new Update();
Iterator<String> iterator = json.keys();
while(iterator.hasNext()) {
String key = iterator.next();
if(!key.equals("MyId")) {
Object value = json.get(key);
update.set(key, value);
}
}
mongoTemplate.updateFirst(query, update, entityClass);
There may be some other way to get keyset from json, you can use according to your convenience.
You can use BasicDbObject to get keyset.
you can get BasicDbObject using mongoTemplate.getConverter().

spring data mongodb NearQuery add another criteria

Is it possible to add a Criteria to a NearQuery?
Currently I am doing this:
public List<UserLocation> getUserNearLocation(Point p, double min, double max){
NearQuery query = NearQuery.near(p).minDistance(new Distance(min, Metrics.KILOMETERS)).maxDistance(new Distance(max, Metrics.KILOMETERS));
GeoResults<UserLocation> results = mongoTemplate.geoNear(query, UserLocation.class);
List<UserLocation> all = new ArrayList<UserLocation>();
Iterator<GeoResult<UserLocation>> iter = results.iterator();
while (iter.hasNext()){
GeoResult<UserLocation> temp = iter.next();
all.add(temp.getContent());
}
return all;
}
I would like to add another criteria to the query, is it possible and how?
just add an additional query like shown below.
NearQuery query = NearQuery.near(new Point(1, 2)).query(Query.query(Criteria.where("foo").is("bar")));

Retrieving related entities using RetrieveMultipleRequest

I have an entity called Invoice and an entity called InvoiceItem.
There is a one to many relationship called new_invoice_invoiceitem.
There is a LookupAttribute in InvoiceItem called new_parent_invoice_invoiceitem.
I am trying to retrieve the InvoiceItems that are related to the Invoice with a particular ID using the following code:
QueryExpression query = new QueryExpression();
query.EntityName = "new_invoiceitem";
query.ColumnSet = new AllColumns();
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = "new_parent_invoice_invoiceitem";
condition.Values = new object [] { new Guid("fe1009cc-e034-49d5-bc59-ab4c3091a6f9") };
condition.Operator = ConditionOperator.Equal;
FilterExpression filter = new FilterExpression();
filter.AddCondition(condition);
query.Criteria = filter;
RetrieveMultipleRequest request = new RetrieveMultipleRequest();
request.Query = query;
RetrieveMultipleResponse response = (RetrieveMultipleResponse)crmService.Execute(request);
BusinessEntityCollection bec = response.BusinessEntityCollection;
The code runs without errors but the BusinessEntityCollection is always empty even though there are records in Dynamics.
Any idea what I'm doing wrong?
Thanks,
David
Try setting request.ReturnDynamicEntities = true

Resources