n1ql.delete not working in spring data couchbase - spring-data

I am using spring data couchbase and I want to write a custom query for deleting all the docs based on some condition
I have below query written down:
#Query("#{#n1ql.delete} WHERE #{#n1ql.filter} AND " +
"accountId = $1 #{#n1ql.returning}")
Mono<Void> delete(String accountId);
But this does not seem to be working. Please help me to fix this issue.

What version are you using?
Please show the calling code and how you determine it does not work.
Two things to check-
If the document to be deleted was just inserted, it may not yet have been indexed.
This is a reactive repository - tbe n1ql wiil not be executed unless the result is collected.

Related

Mongodb I can see the size of the collection but, find() does not return anything

I am new to working with Mongo. I recently taken over our LearningLocker database from a previous employee. I can see using show dbs, the database has 4.188GB. But even using a simple db.learninglocker.find() is not returning anything. Any suggestions on how to review the data?
You should pass down an object as argument to the find function:
db.learninglocker.find({})

Why Spring Data doesn't support returning entity for modifying queries?

When implementing a system which creates tasks that need to be resolved by some workers, my idea would be to create a table which would have some task definition along with a status, e.g. for document review we'd have something like reviewId, documentId, reviewerId, reviewTime.
When documents are uploaded to the system we'd just store the documentId along with a generated reviewId and leave the reviewerId and reviewTime empty. When next reviewer comes along and starts the review we'd just set his id and current time to mark the job as "in progress" (I deliberately skip the case where the reviewer takes a long time, or dies during the review).
When implementing such a use case in e.g. PostgreSQL we could use the UPDATE review SET reviewerId = :reviewerId, reviewTime: reviewTime WHERE reviewId = (SELECT reviewId from review WHERE reviewId is null AND reviewTime is null FOR UPDATE SKIP LOCKED LIMIT 1) RETURNING reviewId, documentId, reviewerId, reviewTime (so basically update the first non-taken row, using SKIP LOCKED to skip any already in-processing rows).
But when moving from native solution to JDBC and beyond, I'm having troubles implementing this:
Spring Data JPA and Spring Data JDBC don't allow the #Modifying query to return anything else than void/boolean/int and force us to perform 2 queries in a single transaction - one for the first pending row, and second one with the update
one alternative would be to use a stored procedure but I really hate the idea of storing such logic so away from the code
other alternative would be to use a persistent queue and skip the database all along but this introduced additional infrastructure components that need to be maintained and learned. Any suggestions are welcome though.
Am I missing something? Is it possible to have it all or do we have to settle for multiple queries or stored procedures?
Why Spring Data doesn't support returning entity for modifying queries?
Because it seems like a rather special thing to do and Spring Data JDBC tries to focus on the essential stuff.
Is it possible to have it all or do we have to settle for multiple queries or stored procedures?
It is certainly possible to do this.
You can implement a custom method using an injected JdbcTemplate.

Spring Data R2DBC - Backpressure not taken into account?

This thread is a continuation of the Github issue at: https://github.com/spring-projects/spring-data-r2dbc/issues/194
Context:
Hi,
I just tried a very simple Exemple, based on two reactive repositories:
Given br, a r2dbc crud repo, and cr, another r2dbc crud repo:
br.findAll()
.flatMap(br -> {
return cr.findById(br.getPropertyOne())
.doOnNext(c -> br.setProperty2(c))
.thenReturn(br);
})
.collectList().block();
This code samples never completes (only the 250 first, or so, entries reach the .collectList operator). After some digging, adding some onBackpressureXXX operator after the findAll seems to "fix" the issue by... well, dropping elements or buffering them.
At this point, my understanding is that the r2dbc reactive repositories doesn't uses the consumer feedback mechanism which removes a significant part of r2dbc's benefits.
Am I wrong ? Is there any better way to achieve the same objective ?
Thanks !
Suggestion from #mp911de:
Avoid stream creation while another stream is active (Famous quote: Do not cross the streams) as general rule.
If you want to fetch related data, then ideally collect all results as List and then run subqueries. This way, the initial response stream is consumed and the connection is free to fetch additional results.
Something like the following snippet should do the job:
br.findAll().collectList()
.flatMap(it -> {
List<Mono<Reference>> refs = new ArrayList<>();
for (Person p : it) {
refs.add(cr.findById(br.getPropertyOne()).doOnNext(…));
}
return Flux.concat(refs).thenReturn(it);
});
But this removes the benefit of streaming the data without keeping it all in memory (my final step not being to list but to stream-write to output to some file).
Any help on this one ?

Couchbase Sync-Gateway View Index Failure

I'm using Couchbase to power the back end of my mobile app and am experiencing a strange error when using views.
I have a view set up to fetch a specific document type and am querying that view via the Sync-Gateway admin API. Normally it works well but I've found that if a document has been recently added to the database then the view query will return 0 results on the first request. The second identical request will then return the expected response.
I suspect that the new document hasn't been indexed by couchbase yet and the query triggers a re-indexing of documents. What I'm wondering is if there's a way of notifying couchbase that I'm about to query the view and to prepare the documents in advance. I don't want to have to perform 2 requests for each query.
Has anyone else come across this issue?
Any solutions?
By default, Sync Gateway allows using a "stale" index, meaning a query won't necessarily rebuild the index before processing a query.
To override this, add stale=false to your query.
(Allowed options are false, ok, and update_after. The default is update_after.)

Able to get collection, but not filtered data in production version of Slim app using Eloquent

I've been working on a Slim 2 and have just recently started deploying to a production server. Everything seems to be working okay so far. I'm able to log in so I know that I'm connecting to the database just fine. It recognized who I'm logged in as recognized what permissions I have as this user. I have another table with several entries. When I do...
$collection = collect($app->item->where('user_id', $userId)->get());
and then...
print_r($collection);
on the production server, I see the whole collection just like I do on the development server, but when I add...
$pack = $collection->where('status', 1);
and instead of printing the collection, try to print the pack like...
print_r($pack);
this message comes back...
Illuminate\Support\Collection Object ( [items:protected] => Array ( ) )
where on the development version I get the filtered collection as I would expect. How can I alter the code to work in both development and production environments?
Most likely you don't have records in the production database with a status of 1 and you do have records with a status of 1 in development.
Check the database directly in production to verify.
Apparently the collection only has strings in it or it will only match a string... this works!
$pack = $collection->where('status', '1');
Check your Eloquent version. Before 5.3 collections used strict comparison when using where() and to use loose you use whereLoose() but as of 5.3 where() is a loose comparison and whereStrict() is the strict method call.