play-reactivemongo dealing with Indexes - scala

I've found that in order to create an index in a collection I should use the indexesManager:
collection.indexesManager.ensure(...)
I would like to know which is the right place for this function call.
I put this call in the function of the Controller that performs the insertion of documents in the collection, and it works.
But I guess that it is not necessary to call this function on each insertion.
Is there a way to make this call only once when the DB is initialized?
Thanks

In reactivemongo 2.11, you should be able to get the current database instance like this :
val db = current.injector.instanceOf[ReactiveMongoApi].database
Please note that this line will give you back a Future[DefaultDB]. Then, you can do what you want by simply mapping on this Future :
db.map(_.collection("myCollection")))

Related

#ExistQuery in Spring data mongodb

Hello I would like to do exist query in spring mongo repository. I read about #ExistQuery but I don't know how write query inside, my method now:
#ExistsQuery("{ 'userAccount.socialTokenId': ?1}")
boolean existBySocialAccountId(String socialAccountId);
But I getting IndexOutOfBoundsException, 'userAccount' is a List of objects which contain variable socialTokenId. I know that I can just get whole User object and find it by myself but I would like to optimize my queries :).
I believe your problem is that the paramaters are zero indexed, so there is no parameter with index of 1, which is causing an IndexOutOfBoundsException.
Try changing your code to the following:
#ExistsQuery("{ 'userAccount.socialTokenId': ?0}")
boolean existBySocialAccountId(String socialAccountId);

Peewee difference between select().limit(1) and get()

whats the difference between Peewee's select with a limit(1) and get AFAIK they they both perform the same query but get raises an exception when it doesn't find a result to the query, which is better to use and why? is there any difference in a performance point of view, a logical point of view or a coding standard that i might have missed?
Not a whole lot, really. The .get() API allows you to retrieve a single record efficiently, raising an exception if the record is not found. If instead you call .select().limit(1), you still need to either index into the result set, or advance the results iterator to grab the obj.
Basically, .get() is a short-hand for select limit 1, then grab the row (if exists), raising special exception type if no match is found.

How to call 'like any' PostgreSQL function in JPQL

I have next issue:
I have list of names, based on which I want to filter.The problem is that I have not full names(Because I'm receiving them from ui), and I have, for example, this array= ['Joh', 'Michae'].
So, I want to filter based on this array.
I wrote query in PostgreSQL
select * from q_ob_person where name like any (array['%Хомяченко%', '%Вартопуз%']);
And I want to ask how to write JPQL query gor this.
Is there an option to call postgresql function like any from JPQL?
JPA 2.1 allows invocation of any SQL function using
FUNCTION(sqlFuncName, sqlArgs)
So you could likely do something like (note never tried this LIKE ANY you refer to, just play around with it)
FUNCTION("LIKE", FUNCTION("ANY", arrayField))
Obviously by invoking SQL functions specific to a particular RDBMS you lose database independence (in case that's of importance).

Discard values while inserting and updating data using slick

I am using slick with play2.
I have multiple fields in the database which are managed by the database. I don't want to create or update them, however I want to get them while reading the values.
For example, suppose I have
case class MappedDummyTable(id: Int, .. 20 other fields, modified_time: Optional[Timestamp])
which maps Dummy in the database. modified_time is managed by the database.
The problem is during insert or update, I create an instance of MappedDummyTable without the modified time attribute and pass it to slick for create/update like
TableQuery[MappedDummyTable].insert(instanceOfMappedDummyTable)
For this, Slick creates query as
Insert INTO MappedDummyTable(id,....,modified_time) Values(1,....,null)
and updates the modified_time as NULL, which I don't want. I want Slick to ignore the fields while updating and creating.
For updating, I can do
TableQuery[MappedDummyTable].map(fieldsToBeUpdated).update(values)
but this leads to 20 odd fields in the map method which looks ugly.
Is there any better way?
Update:
The best solution that I found was using multiple projection. I created one projection to get the values and another to update and insert the data
maybe you need to write some triggers in table if you don't want to write code like row => (row.id,...other 20 fields)
or try use None instead of null?
I believe that the solution with mapping non-default field is the only way to do it with Slick. To make it less ugly you can define function ignoreDefaults on MappedDummyTable that will return only non default value and function in companion object to MappedDummyTable case class that returns projection
TableQuery[MappedDummyTable].map(MappedDummyTable.ignoreDefaults).insert(instanceOfMappedDummyTable.ignoreDefaults)

ExecuteSprocAccessor does not function for CUD operations?

I have several stored procedures in my database. For example a delete stored procedure like:
alter procedure [dbo].[DeleteFactor]
#Id uniqueidentifier
as
begin
delete from Factors where Id = #Id
end
When I call this from code like this:
dc.ExecuteSprocAccessor("DeleteFactor", id);
then the row does not get deleted. However this code functions:
dc.ExecuteNonQuery("DeleteFactor", id);
id is a passed in parameter and of type Guid.
Can anyone explain why the second does work and the first approach does not? I find it quite strange as the first method is clearly to be used with stored procedures.
According to Retrieving Data as Objects, the ExecuteSprocAccessor method uses deferred execution (ala LINQ). So, in the first approach, since you are not accessing the results of the DeleteFactor stored procedure the SQL call is not being made.
I would use the second method anyway since you really are executing a non-query. Also, the first approach may lead to some confusion since the ExecuteSprocAccessor is designed to retrieve data. e.g. "Is data supposed to be returned here? Maybe something was missed?"
Just call ToArray or ToList on the result of your ExecuteSprocAccessor to make it execute.