MongoDB the difference between db.getCollection.find and db.tablename.find? - mongodb

What is the difference between:
db.getCollection('booking').find()
and
db.booking.find()
Are they exactly the same, or when should I use which one?
db.getCollection('booking').find({_id:"0J0DR"})
db.booking.find({_id:"0J0DR"})

Yes, they are exactly the same and you can use either.
The first form db.getCollection(collectionName).find() becomes handy when your collection name contains special characters that will otherwise render the other syntax redundant.
Example:
Suppose your collection has a name that begin with _ or matches a database shell method or has a space, then you can use db.getCollection("booking trips").find() or db["booking trips"].find() where doing db.booking trips.find() is impossible.

I prefer using db.collection() to either as it will work on nonexistent collections, which is particularly useful when for example creating the first user in a users collection that doesn't yet exist.
db.collection('users').findOneAndUpdate(...) // Won't throw even if the collection doesn't exist yet

In addition to the previous answers, on the shell, they might be exactly the same but in real IDE (like PyCharm), db.getCollection(collectionName) gives you back the whole doculment even with out the find() method.

Related

Is there another way way to replace paginate() with take()->get() where query param is present? (Laravel 9)

Usually I use paginate when I want the user to view a list (or a narrowed down list based on filters). Simple example below:
Thing::query()
->orderByDesc('created_at')
->paginate(40);
If I wanted the user to view a short list, like get the five newest models, I would create a separate api with a query like below:
Thing::query()
->orderByDesc('created_at')
->take(5)
->get();
I want to combine the two eloquent queries in such a way that it gets the paginated list by default, but will take 5 if the query param 'take=5' is present. I can do this the following way:
Thing::query()
->orderByDesc('created_at')
->when(
$request->query('take'),
fn ($query, $count) => $query->take((int)$count)->get(),
fn ($query) => $query->paginate(50)
);
The above works but has been described by a colleague as a little confusing, since the 3rd argument to when() is if the first argument is false (documentation) but that isn't immediately apparent when viewing the code. The "confusing" part might be subjective here but I would like to make sure my code is quickly understood by other devs as best as possible.
Does anyone know of a simpler/clearer or just another way to achieve this? In an ideal world the take()->get() would only exist in the when() method and paginate() would exist outside of it, but be overridden by the when() condition if true.
Note: I anticipate some people might say that they should remain as separate api's, however in my opinion the extra logic here is so simple that the gain in reduced code outweighs the gain in "do one thing well".

Why use result sets rather than variables in Sybase?

In a Sybase database I am working with result sets are used (misused?) as variables.
For example, one often finds lines such as the following:
select SOMETHING = 'bla'
"SOMETHING" is technically a result set ... and the content of the result set is used by the application accessing the database. Since "SOMETHING" is not a variable, it does not get declared anywhere.
I have never seen this kind of hack before (and colleagues of mine couldn't explain to me the reason why it was done that way) and I have not found anything about it on google.
Is there some reference available that explains why one would want to use such a hack as opposed to "normal" variables?
I think you are not reading this correctly. This query simply means that there is a one-column result set with the column named 'SOMETHING'. This query is equivalent to: SELECT 'bla' AS SOMETHING

How to chain multiple assertThat statement in AssertJ

Here is an example:
assertThat(commentById.getId()).isNotNull();
assertThat(commentById.getContent()).isNotBlank();
assertThat(commentById.getAuthor()).isNotNull();
assertThat(commentById.getAuthor().getUsername()).isNotBlank();
assertThat(commentById.getAuthor().getAvatar()).isNotBlank();
assertThat(commentById.getAuthor().getId()).isNotNull();
Is there anyway to chain this into a single assertThat statement
Sorry for the unclear question. I mean, is there some fluent method calls to chain multiple assertThat statement together. Here is an example I can think of:
assertThat(commentById)
.isNotNull()
.and(Comment::getID).isNotNull()
.and(Comment::getContent).isNotBlank()
.and(Comment::getAuthor).is(author->{
author.isNotNull()
.and(User::getID).isNotNull()
.and(User::getAvatar).isNotBlank()
.and(User::getUsername).isNotBlank()
});
You can utilize satisfies method:
assertThat(commentById.getId()).isNotNull();
assertThat(commentById.getContent()).isNotBlank();
assertThat(commentById.getAuthor()).isNotNull().satisfies(author -> {
assertThat(author.getUsername()).isNotBlank();
assertThat(author.getAvatar()).isNotBlank();
assertThat(author.getId()).isNotNull();
});
This helps to eliminate repeating parts of code while testing nested structures.
If you want the commentById object itself to be tested by "one-liner", it is theoretically possible to apply same approach onto it (assertThat(commentById).satisfies(c -> {assertThat(c.getId()).isNotNull(); ...})), however I state it here only to literally answer your question, actually I don't see any benefit of such expression.
This is not possible at the moment, what is possible is to use extracting but that implies navigating from the current actual to the extracted one without being able to go back to the original actual.

Does mediaResponse really support array of mediaObject?

As the document says, MediaResponse contains mediaObjects property, and mediaObjects is array of mediaObject, but when I tried to put multiple mediaObjects, I got this error:
MalformedResponse at
expected_inputs[0].input_prompt.rich_initial_prompt.items1.media_response:
Only 1 media_object is allowed. First media_object will be used while
rest will be filtered.
Then what is the point of having an array of mediaObject?
There are several places in the protocol that contain an array where only one object is permitted in the array. One assumes that the designers wanted to make it expandable in the future without having to add special casing.
In this case, it sorta makes sense - right now we can only send one media object as part of the reply. It might be reasonable that, in the future, we could send one or more without having to come back to our webhook.

How to know if a PostfixExpression belongs to a for statement?

I'm using eclipse parser to work with expressions and statements in java code.
I have a function:
public boolean visit(PostfixExpression node)
which deals with Postfix expressoins, such ass i++;
Problem is i want to distinguish between a for statement postfix, and other postfixes.
I thought maybe i could get to the node's parent and somehow check if it's a for. Something like node.getParent()... but node.getParent() doesn't return an expression.
Any ideas how to recognize if the PostfixExpression belongs to a for loop?
Thanks
edit:
By "for statement postfix" i mean the postfix in the for loop's first line. Such as:
for(i=0;i<10;i++)
So i want to distinguish this i++ from other i++'s.
Can't you just call ASTNode.getParent() to see what kind of statement the expression is contained in?
I solved this by creating a for_updaters List (using node.updaters()) and updating it every time i visit a for loop (could also be nested loops). Also, whenever i come across a PostfixExpression (including for updaters), i add it to another List, and then delete from this List all similar occurrences that appear in for_updaters List. This way i'm only left with non-for-updaters Postfixes. This also works for me because every time i visit a for loop i clear both Lists, so no worries about duplicate variable names.
Note: node.updaters() returns the exact full expression: [i++]. But i only need i. It's easy to extract it by converting the updater to String and then use substring().