Scala, Quill - how to compare values with case-insensitive? - scala

I created a quill query, which should find some data in database by given parameter:
val toFind = "SomeName"
val query = query.find(value => infix"$value = ${lift(toFind)}".as[Boolean])
It works fine when for example I have data in database "SomeName", but if I want to have same results by passing there "somename" I found nothing. The problem is with data case-sensitive.
Is it possible to always find values with case-insensitive way? In quill docs I have not found anything about it.

Ok, I found a solution. It is enough to add LOWER() sql function to infix:
val query = query.find(value => infix"LOWER($value) = ${lift(toFind.toLowerCase)}".as[Boolean])

Related

Mongo DB find - SQL Like - wildcard in the middle

This question is very similar to How to query MongoDB with "like"?, yet I have not been able to use that or the documentation here https://docs.mongodb.com/manual/reference/operator/query/regex/ to figure out the query that I need.
I need to find documents in a mongo collection which has values of following format in a field:
"key->some_name::details->(value = '{wild_card_value_here}'):sort->by_name"
In SQL this query would look like
SELECT * from some_Table where field like 'key->some_name::details->(value = ''%''):sort->by_name'
Note that single quote is part of the string
Here's what I tried with mongo:
db.getCollection('collection_name').find({"some_field":{$regex:/^key->some_name::details->(value = '.*'):sort->by_name/}})
But it returns 0 documents. I also tried this which did not work either:
db.getCollection('collection_name').find({"some_field":"key->some_name::details->(value = '/.*/'):sort->by_name"})
I'm unsure if the syntax itself is issue or the special characters in the string like , -> : etc.
EDIT:
Example document that I want to be found:
{
...
"some_field":"key->some_name::details->(value = 'id_1'):sort->by_name"
...
}
and
{
...
"some_field":"key->some_name::details->(value = 'id_2'):sort->by_name"
...
}
Turns out this was a matter of escaping special characters ( and ), The query that worked is:
db.getCollection('collection_name').find({"some_field":{$regex:/^key->some_name::details->\(value = '.*'\):sort->by_name/}})

How to save dataframe to Elasticsearch with mappings

I have following code to save dataframe to elastic search. It works well.
val conf = new SparkConf(true).set("spark.cassandra.connection.host", host)
conf.set("spark.es.index.auto.create", "true")
conf.set("spark.es.nodes", host)
val features = sqlContext.read.parquet(input)
features.write.format("org.elasticsearch.spark.sql")
.mode(SaveMode.Append)
.option("es.resource","{ts}/log").save()
It autocreates index when it is not there. But when I try to query on some field. It shows following error
Set fielddata=true on [country] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.
I am aware of the mappings to make text fields as keywords
{
"your_field": {
"type" "keyword",
"index": true
}
}
But I couldn't find how to use these mappings when creating index with this code
In my experience, Elasticsearch for hadoop also creates a .keyword with keyword type already for you!
Try using country.keyword

Scala Postgres IN Operator

I'm developing a web application based on Activator and Postgres.
I am trying to perform the following SQL query:
SELECT *
FROM table t_0
WHERE t_0.category IN (?)
then to populate the query I am using the following Scala code
val readQuery = """ SELECT * FROM table t_0 WHERE t_0.category IN (?) """
val categories = Array("free time", "living")
val insertValues = Array(categories)
val queryResult = await { connection.sendPreparedStatement(readQuery, insertValues) }
Even though there are some records in the database I always get an empty set, I have already tried with some forms of Array[Byte], but I have never managed to get results.
Does anybody have some tips or trick that I can use?
Thanks!

Pagination with native query in slick

I am using Slick to connect to Postgres Database in our application. I have a generic filtering logic, where a Filter object will be passed from the UI, and it should return results with pagination. The Filter object should be generic so that it can be re-used.
Pseudo code of filter object is given below:
Filter = {
type: table
prop: List_of_conditions
page : 1
size : 10
}
Currently, I am building a native SQL from the Filter object and executing it. However, I am not able to use take and drop before the query is actually getting executed. It is currently getting all the results, and then dropping the unnecessary records.
I know how to do it with the slick queries, but not sure how to use pagination with the native queries?
val res = StaticQuery.queryNA[Entity](queryStr).list.drop((filter.pageNo- 1) * filter.pageSize).take(filter.pageSize)
I am using Slick 2.1
When you are using plain sql, you can't use the collection operators to build a query. You have to do it all in SQL:
val limit = filter.pageSize
val offset = (filter.pageNo- 1) * filter.pageSize
val res = StaticQuery.queryNA[Entity](queryStr ++ s" LIMIT $limit OFFSET $offset").list
I haven't tested it but i would suggest you to try to move .list call to the end
val res = StaticQuery.queryNA[Entity](queryStr).drop((filter.pageNo- 1) * filter.pageSize).take(filter.pageSize).list

Does Mongodb have a special value that's ignored in queries?

My web application runs on MongoDB, using python and pyMongo. I get this scenario a lot - code that reads something like:
from pymongo import Connnection
users = Connection().db.users
def findUsers(firstName=None, lastName=None, age=None):
criteria = {}
if firstName:
criteria['firstName'] = firstName
if lastName:
criteria['lastName'] = lastName
if age:
criteria['age'] = age
query = users.find(criteria)
return query
I find that kind of messy how I need an if statement for every value that's optional to figure out if it's needs to go into the search criteria. If only there were a special query value that mongo ignored in queries. Then my code could look like this:
def findUsers(firstName=<ignored by mongo>, lastName=<ignored by mongo>, age=<ignored by mongo>):
query = users.find({'firstName':firstName, 'lastName':lastName, 'age':age})
return query
Now isn't that so much cleaner than before, especially if you have many more optional parameters. Any parameters that aren't specified default to something mongo just ignores. Is there any way to do this? Or at-least something more concise than what I currently have?
You're probably better off filtering your empty values in Python. You don't need a separate if-statement for each of your values. The local variables can be accessed by locals(), so you can create a dictionary by filtering out all keys with None value.
def findUsers(firstName=None, lastName=None, age=None):
loc = locals()
criteria = {k:loc[k] for k in loc if loc[k] != None}
query = users.find(criteria)
Note that this syntax uses dictionary comprehensions, introduced in Python 2.7. If you're running an earlier version of Python, you need to replace that one line with
criteria = dict((k, loc[k]) for k in loc if loc[k] != None)