Spring data mongodb in clause with case insensitive - spring-data-mongodb

Is it possible to use IN clause in spring data mongodb with case insensitivity?
For example my Customer model have a field email and I want to get the list of customers from the list of emails I have.
Normally in JPA, I can get the list of customers from emails using findAllByEmailIn(List<String> emails)
I am thinking of setting the emails to lowercase, but this still is not as safe as case insensitive.
Something like:
findAllByEmailIn(emails.stream().map(String::toLowerCase).collect(Collectors.toList()))
OR
Query query = new Query();
query.addCriteria(where("email").in(emails.stream()
.map(String::toLowerCase).collect(Collectors.toList())));
return m_mongoTemplate.find(query, Customer.class);
Is there a way to use IN clause with case insensitivity? Either by JPA findAllBy magic, or by query criterias?

You can try using RegEx
{ email: { $in: [ /^test1#Gmail.Com/i, /^TEST2#gmail.COM/i ] } }

Related

MongoDB comparison

I am trying to retrieve data in my MongoDB database. If I have the following below in my mongoDB database, I want to select the Password given the Username. So in this case, I will be looking through the database for a Username that is 'e' and retrieving the password associated with that specific Username. I've tried looking everywhere but I can't seem to find a solution on how to do it. I am using express, node, and mongoDB for this personal project. What I have so far is just looking up with database with .find({ Username: Username} and it outputs the entire JSON object.
To clarify, I will be sending a request with a Username of value 'e' and looking it up the database trying to retrieve the value of Password.
{
_id: 62d7712e6d6732706b46094e,
Username: 'e',
Password: 'hi',
__v: 0
}
find takes multiple inputs you can give the select statements also in find itself
so the query will be like
db.collectionName.find({username:'e'},{_id:0,password:1})
mongo by default fetch _id all the time by default so you need to specifically mention to not fetch _id thus _id :0
for such scenarios, there are 2 options if username is unique i would suggest to go with findOne rather then find
db.collectionName.findOne({username:'e'}).password
the same will work if you have multiple records with same username but you want only the first record
but if you want data of all the records as array
db.collectionName.find({username:'e'},{_id:0,password:1})..map( function(u) { return u.password; } )

Order by best match of string column in EF Core

I am implementing a search feature for the users in our api. The search will query our db to fetch the first N users matching the search term. I want to order the user after "best match" so the most relevant user is on top.
What I'd like to do is something like:
var users = await _dbContext.Users
.IncludeUserData()
.Where(u => u.Name.Contains(searchTerm))
.OrderBy(u => u.Name.IndexOf(searchTerm)) <- This row is not possible
.ToListAsync();
Where basically a name that contains the search term early is ordered before a user whose name contains the term late.
E.g.
Simon Carlsson should come before Carl Simonsson if the searchTerm is "Simon"
Using SQL Server as the DB provider
How would I achieve an order by query where users with names better matching the searchTerm are sorted higher up in the list?
After some more searching this method of importing functions from the DB provider was found:
[DbFunction("CHARINDEX", IsBuiltIn = true)]
public static long CHARINDEX(string substring, string str)
{
throw new NotImplementedException();
}
Put this in user dbContext class. It will bind to the CHARINDEX function in SQL Server.
https://learn.microsoft.com/en-us/ef/core/querying/user-defined-function-mapping
Then use it to sort the query:
.sortBy(u => DbContext.CHARINDEX(searchTerm, u.name))
Have you tried the LIKE operator?
You may find this useful
Entity framework EF.Functions.Like vs string.Contains

Modify and delete document in Cloudant IBM Database

Is it possible to modify document or delete in Cloudant Database by query?
I assume the questioner is looking for equivalent functionality to SQL's:
UPDATE db SET x = 10 WHERE y > 100;
If that is the question then the answer is that Cloudant does not have such functionality, only an atomic update operation.
The equivalent of the UPDATE statement could be achieved by combining a call to the Cloudant Query API and making updates using the bulk API.
Another option is to use the couchtato iterator tool which allows bulk changes to be made to Cloudant databases.
To delete a document you have to know the document _id, if you do not know the _id then you have to look for the document in your db, retrieve it and then get the _id.
To retrieve a document you can use a selector. For example, let's say that you have a document that contains a "name" field, your selector would be something like
selector = {"name": {"$eq": "name that you want"}}
So for python code you would have something like
def retrieve_db_data(db_name, selector):
client = connect_to_db()
db = client[db_name]
results = db.get_query_result(selector)
data = results.all()
return data
In "data" you will have the _id
then you can use something like this to delete the data
def delete_document(db_name, doc_id):
client = connect_to_db()
client.connect()
db = client[db_name]
document = db[doc_id]
document.delete()

Cloud Datastore 'like' query

I've an entity in Google Cloud Datastore. One of the properties is array of strings. For example:
property: skills
Entity 1:
value: ["mysql","sqlserver","postgresql","sqllite","sql-server-2008","sql"]
Entity 2:
value: ["css","css3"]
Now, I need to query for those entities that contain array elements css*
In typical SQL, it'll be select * from kindName where skills like 'css%'
I tried select * from kindName where skills = 'css', which works fine but how can I get entities that have css* elements similar to the SQL query?
Or
What's the best way to model the data for this?
You can do inequality range checks on a single indexed property as given in the example below. Range checks on strings are essentially how you can perform prefix searching on strings.
SELECT * from yourKind WHERE skills >= "css" AND skills < "cst"
As an example, here is the query performed on some sample data I created in the UI Console for Cloud Datastore:

How to search arrays for values in Google Cloud Datastore

Assuming we have an entity in Google Cloud Datastore - "Job" and it has some Access Control Tags:
["admin", "manager"]
and we have a user that has some Access Control Tags
["admin", "super_user"]
We would like to pull back all Jobs that this user has access to; e.g. in SQL something like
SELECT * from Job where tags INCLUDE "admin" OR tags INCLUDE "super_user"
OR queries are not supported, is there another way to achieve this?
Could you query the datastore model using ndb.OR? Something like in this example:
query = Article.query(ndb.AND(Article.tags == 'python',
ndb.OR(Article.tags.IN(['ruby', 'jruby']),
ndb.AND(Article.tags == 'php',
Article.tags != 'perl'))))
You can query to retrieve multiple values like the following:
If you have array of multiple datastore Id's like following:
[1,2,3,4]
You can query with gstore-node Package
var userData = await UserModel.get([1,2,3,4]);
Hope this will help you.
Thanks
For that you need to store the data in array format in google cloud datastore. in here we can't use OR condition. so you can use > and < for equlity and also you can use the add_filter for that

Resources