i wanted to do a direct update to mongodb and setting someflag to either true or false for my use case. To be effecient i do not want to query all documents and set the someflag and save it back to db. i just want to directly update it on db just like when doing update on mongodb terminal.
Here is the sample document. NOTE: these documents can number from 1 ~ N so i need to handle efficiently big datas
{
_id: 60db378d0abb980372f06fc1
someid: 23cad24fc5d0290f7d5274f5
somedata: some data of mine
flag: false
}
Currently im doing an #Query method on my repository
#Query(value ="{someid: ?0}, {$set: {flag: false}}")
void updateFlag(String someid)
Using the above syntax, it doesnt work, i always get an exception message below;
Failed to instantiate void using constructor NO_CONSTRUCTOR with
arguments
How do i perform a direct update effeciently without querying all those document and updating it back to db?
Use the BulkOperations class (https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/BulkOperations.html)
Sample codes:
Spring Data Mongodb Bulk Operation Example
Related
We are facing issues while updating tables having column with datatype timestamp.
Insert and Update works fine if we use ignite repository for both.
Insert or Update works fine if we use native queries for both.
Insert via Ignite repository and update via native queries results in an below error
class org.apache.ignite.binary.BinaryObjectException: Invalid flag value: 32
at org.apache.ignite.internal.binary.builder.BinaryBuilderReader.parseValue(BinaryBuilderReader.java:863)
at org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:290)
at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:103)
at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:56)
at org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:297)
at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:103)
at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:56)
at org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:297)
```
If you can post example code, this would make a good bug report.
https://github.com/apache/ignite/blob/876a2ca190dbd88f42bc7acecff8b7783ce7ce54/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java#L515
I am required to execute a stored procedure in a SQL server to fetch some data, and since I will later save the data into a Mongo and this one is with ReactiveMongoTemplate and so on, I introduced Spring R2DBC.
implementation("org.springframework.data:spring-data-r2dbc:1.0.0.RELEASE")
implementation("io.r2dbc:r2dbc-mssql:0.8.1.RELEASE")
I see that I can do SELECT and INSERT and so on with R2DBC, but is it possible to EXEC prod_name? I tried it and it hangs forever and then the test terminates, without success but neither failure. The last line of log is:
io.r2dbc.mssql.QUERY - Executing query: EXEC "SCHEMA"."MY_PROCEDURE"
The code is like:
public Flux<Coupon> selectWithProcedure() {
return databaseClient
.execute("EXEC \"SCHEMA\".\"MY_PROCEDURE\" ")
.as(Coupon.class)
.fetch().all()
.doOnNext(coupon -> {
coupon.setCouponStatusRefFromId(coupon.getCouponStatusRefId());
});
}
And it seems that no data is retrieved.
If I test some other methods with simple queries like SELECT... it works. But the problem is, DBAs do not allow my app to read table data, instead, they create a procedure for me. If this query is not possible, I must go with traditional JPA way and going reactive at Mongo side has lost its sense.
Well. I just saw this:
https://github.com/r2dbc/r2dbc-mssql, version 0.8.1:
Next steps:
Execution of stored procedures
Add support for TVP and UDTs
And:
https://r2dbc.io/2019/05/13/r2dbc-0-8-milestone-8-released
We already have a few tickets lined up for the next milestone, and we know that they will require further SPI modifications:
Support for Auto-Commit
Connection Validation
Support for Stored Procedures
I'm new user of mongoDB, I have create an application with spring boot/mySql and I want replace database sql to mongoDB.
I did change all things necessary for example, annotations, relations etc ... but I have a problem with request I don't know the similar syntax of #Query in mongoDb.
this my request with sql:
// this calculate the sum of all distance in walk's document
#Query("select sum(distance) from Walk")
public Double sumDistance();
I did read mongoDB aggregate and I know how to use it in console windows with command
$ mongo
$ db.walk.aggregate([{$group:{"_id":"$dateWalk",Count:{$sum:"$distance"}}}])
but, I want use $sum in my program java not in console.
So please, I need your help about the syntax similar to this with mongoDB
// this calculate the sum of all distance in walk's document
#Query("select sum(distance) from Walk")
public Double sumDistance();
thanks in advance :)
You would need to create a custom Repository that would implement the aggregation.
Examples:
https://www.javacodegeeks.com/2016/04/data-aggregation-spring-data-mongodb-spring-boot.html
https://github.com/spring-projects/spring-data-examples/blob/master/mongodb/aggregation/src/main/java/example/springdata/mongodb/aggregation/OrderRepositoryImpl.java
I am using db.runCommand(document) of Java Mongo driver api.
Sample code I am using
Document resultDocument = db.runCommand({
find: 'collectionName',
filter: { startDate:{$gte:'#startDate',$lte:'#endDate'}},
projection: { _id:0}});
I am using find command. My query is returning 101 records only as default batch size is 101. I want to create a cursor as mentioned in api below.
Snippet in mongo documentation:
https://docs.mongodb.org/manual/reference/command/find/#dbcmd.find
Executes a query and returns the first batch of results and the cursor id, from which the client can construct a cursor.
I don't want to give batchSize as I am not sure how many records my query will return. So I want to create a cursor and iterate over it.
Can any one help how to create a cursor from id returned by db.runCommand in mongo java driver to iterate over all the records.
You may get the next batches using
getMore
Use in conjunction with commands that return a cursor, e.g. find and aggregate, to return subsequent batches of documents currently pointed to by the cursor.
I'm trying to do upsert using mongodb driver, here is a code:
BulkWriteOperation builder = coll.initializeUnorderedBulkOperation();
DBObject toDBObject;
for (T entity : entities) {
toDBObject = morphia.toDBObject(entity);
builder.find(toDBObject).upsert().replaceOne(toDBObject);
}
BulkWriteResult result = builder.execute();
where "entity" is morphia object. When I'm running the code first time (there are no entities in the DB, so all of the queries should be insert) it works fine and I see the entities in the database with generated _id field. Second run I'm changing some fields and trying to save changed entities and then I receive the folowing error from mongo:
E11000 duplicate key error collection: statistics.counters index: _id_ dup key: { : ObjectId('56adfbf43d801b870e63be29') }
what I forgot to configure in my example?
I don't know the structure of dbObject, but that bulk Upsert needs a valid query in order to work.
Let's say, for example, that you have a unique (_id) property called "id". A valid query would look like:
builder.find({id: toDBObject.id}).upsert().replaceOne(toDBObject);
This way, the engine can (a) find an object to update and then (b) update it (or, insert if the object wasn't found). Of course, you need the Java syntax for find, but same rule applies: make sure your .find will find something, then do an update.
I believe (just a guess) that the way it's written now will find "all" docs and try to update the first one ... but the behavior you are describing suggests it's finding "no doc" and attempting an insert.