[JAVA-2152] Recognize if there is no find result Created: 12/Mar/16 Updated: 11/Sep/19 Resolved: 14/Mar/16 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | Async, Query Operations |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Task | Priority: | Major - P3 |
| Reporter: | Ben [X] | Assignee: | Unassigned |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
I'm using the asynchronous java driver. I hope you can help me to solve the problem of the following scenario. First, using the "find" operator I want to check if there is an entry in my collection. If yes, the callback will be called and I can use it. If there is no entry in my collection, my application should generate this value and persist it. But how could I recognize that "find" can't find any entry? |
| Comments |
| Comment by Ross Lawley [ 14/Mar/16 ] | |||||||||||||||
|
Given your initial description then collection.find().first(callback); solves the problem described - the callback is called when the blocking io has occurred. However, with the expanded problem of wanting all results and not just the first one then its not. For this scenario use forEach should suffice:
If this is a common pattern for you - you may wish to abstract it into your own special callback helpers. The reason forEach is different and takes a block is because its an abstraction built on top of the AsyncBatchCursor, which can be cumbersome to use correctly. Internally, all Async API's take a callback either returning the result or an error and from this simple callback we can determine if there was an error or not or if the operation completed successfully. The callback API is quite low level and can be quite verbose when coding against it. There are other abstractions built upon callbacks eg: Observables that take away some of the pain nesting callbacks. We've also released an rxJava driver built on top of the async driver because we recognise that callbacks can be cumbersome. I hope that answers your question and clarifies the design. Ross | |||||||||||||||
| Comment by Ben [X] [ 14/Mar/16 ] | |||||||||||||||
|
Hi Ross, then it would be nice if you could change this post to Feature Request, because I would recommend another listener which is called if the query does not find something. "collection.find().first(callback)" is just a hack and no solution. I want all results if there are any results. If not, I want to generate a new document and persist it. I think the following solution could make it a little bit easier to solve such a problem: "collection.find().forEach(resultCallback, noResultCallback, readFinishedCallback);" .first() works for me because there is always one doc in my collection. But There are several other scenarios where this noResultCallback will be useful. It is a default behavior to do something if there is a result and do something else if there is no result. Mh I think it is a strange behavior to expect a Block<Document> and SingleResultCallback<Void> for .forEach() but just a SingleResultCallback<Document> for .first(). A more consistent way to use the .first() method would be to expect also both arguments but Block<Document> apply method is just called one time. Best Regards, | |||||||||||||||
| Comment by Ross Lawley [ 14/Mar/16 ] | |||||||||||||||
|
Hi ChampS Just to let you know the JAVA project is for reporting bugs and feature requests with the Java driver. In general the best place to ask questions using the Java driver is either the mongodb-user Google Group or Stack Overflow as public discussion there can help others learn and resolve similar issues. A collection.find().first(callback) will return the first result or null. However, I think findOneAndUpdate with $setOnInsert to set the document values if it doesn't exist meets your requirement without the risk of a race condition. By using returnOriginal you should be able to determine if the document already existed. Hope that helps, Ross |