Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Add case sensitive/insensitive querying #3611

Closed
sapkra opened this issue Nov 27, 2018 · 40 comments
Closed

Add case sensitive/insensitive querying #3611

sapkra opened this issue Nov 27, 2018 · 40 comments

Comments

@sapkra
Copy link
Contributor

sapkra commented Nov 27, 2018

Right now we are implementing a search field in our frontend but we noticed that it's not possible to have case insensitive queries. So everything you are typing in our search field has to be case sensitive. That's a big problem!

Solution
A solution would be to have a new field for the where attribute e.g. the name_contains field should also have name_contains_case_insensitive.
Maybe there are better solutions but this was my first idea.

This problem was also noticed in #3301.

@nsignes-harmonicinc
Copy link

I also encountered that need for an entity lookup feature. Adding this in would help a lot, as we need to have both sensitive and insensitive query options, which blocks the easy way out (DB collation).

@SpaceK33z
Copy link
Contributor

I have the same problem too.

Django names this filter "icontains", e.g. name_icontains. Might also be a good name for Prisma.

@mununki
Copy link

mununki commented Dec 28, 2018

I have the same issue here.
As @SpaceK33z raised the e.g. Django filter property, Prisma needs one.

@chuckntaylor
Copy link

chuckntaylor commented Dec 28, 2018

I have hit the same issue myself for a project I'm starting, in which product names need to be searchable in a case insensitive fashion. Is there any sort of manual workaround in the meantime?

@sapkra
Copy link
Contributor Author

sapkra commented Dec 28, 2018

Yes there are some hacks like using a string with all searchable information chained & lowercase. After doing that you have to lowercase the search query and use searchString_contains.

Don't forget to update the string while you are running mutations.

@mununki
Copy link

mununki commented Dec 28, 2018

Is there any hacky way to resolve this?
I have data such as John in DB field. How can I run query and filter for this kind of data in DB?

If I tried to change my args in resolvers to uppercase or lowercase, it can be matched with first input letter, but no way after second letter input.

someResolver: (root, args, ctx, info) => {
  const match = ctx.prisma.users({
    where: {
      OR: [
            { name_starts_with: args.search.toUpperCase() },
            { name_starts_with: args.search.toLowerCase() }
          ]
        }
    }
  })
}

@Putnam14
Copy link

Putnam14 commented Jan 16, 2019

A work around I'm implementing right now is having a separate Index type for whatever you're going to be querying, and store the relevant data there lowercased. Then you can search with .toLowerCase() on your args.

In my case, I have a Book type with author, title, isbn, description, etc. I have a BookIndex with the author, title, and isbn, author and title being case insensitive. I retrieve the ISBN from there and then search query for the actual data I want.

E: If you want to see more on how I implemented the work-around, I wrote a blog post about it: https://bridgerputnam.me/blog/case-insensitive-search-with-prisma-using-indexes

@williamluke4
Copy link

Hey @schickling, Has there been any progress on this or at least a recommended workaround?

@williamluke4
Copy link

This is what I'm currently using

const variables = {
  where:{
    OR: [
      {name_contains: inputValue},
      {name_contains: inputValue.toLowerCase()},
      {name_contains: inputValue.toUpperCase()},
      {name_contains: titleCase(inputValue)},
    ]
  }
}
export function titleCase(str: string):string {
  let string = str.toLowerCase().split(' ');
  for (var i = 0; i < string.length; i++) {
    string[i] = string[i].charAt(0).toUpperCase() + string[i].slice(1); 
  }
  return string.join(' ');
}

@iRoachie
Copy link

iRoachie commented Apr 3, 2019

@schickling Any updates on this? Kind of lacking when you compare to other ORMs that simulate "LIKE" statements in MySQL.

@schickling
Copy link
Member

That's a great point. Thanks a lot for pinging me @iRoachie. We'll make sure to consider this for the upcoming client API redesign in Prisma 2.

petrbrzek referenced this issue in awesome-prague/backend-app Apr 14, 2019
I must added normalizeTitle as Prisma cannot perform case insensitive search.
Source: prisma/prisma#3611
@chemicalkosek
Copy link

chemicalkosek commented May 9, 2019

Ok, everybody here wrote that it doesn't support case insensitive search.
But in my case, it's actually working on the Prisma demo servers (which internally use MySQL)
But when I have set up my own Prisma Server based on PostgreSQL (using Dokku on Digital Ocean - I couldn't deploy with MySQL - that's another issue) - it doesn't work anymore and it's only case sensitive.
What gives?

My search is actually straightforward:

#schema.graphql
type Query {
...
offers(where: OfferWhereInput, orderBy: OfferOrderByInput): [Offer]!
...
}
#resolvers/Query.js
const { forwardTo } = require("prisma-binding");
const Query = {
 ...
  offers: forwardTo('db'),
 ...
# React Component
const SEARCH_OFFERS_QUERY = gql`
  query SEARCH_OFFERS_QUERY($searchTerm: String!) {
    offers(
      where: {
        OR: [
          { contractorName_contains: $searchTerm }
          { contractorCity_contains: $searchTerm }
          { offerName_contains: $searchTerm }
        ]
      }
    ) {
      id
      contractorName
      offerName
      contractorCity
    }
  }
`;

@taylor-lindores-reeves
Copy link

I would like to know how queries can be case insensitive. Any news on this?

@iRoachie
Copy link

Doing a workaround at the moment by storing an extra variable for every param I'll expose to search.

@taylor-lindores-reeves
Copy link

@iRoachie interestingly enough, I have decided to do the same with the index as suggested by @Putnam14. However, slightly different I think.

I essentially create a relationship between Item and ItemIndex whilst exposing params like you said, like so:


type ItemIndex {
  id: ID! @id
  title: String
  description: String
  image: String
  largeImage: String
  price: Int
  createdAt: DateTime
  item: Item! @relation(link: INLINE)
}

In ItemIndex, I only store the { title } in lower case as well as the { item { id } }. Then I have written a Query which queries each Item based on the relationship of ItemIndex to Item using the id. I do so like this:

    const arr = []
    for (var {
      item: { id }
    } of itemIndexes) {
      const item = await ctx.prisma.query.item({
        where: { id }
      });
      arr.push(item);
    }

The query on the client side has all the params necessary, and returning the array with those params enables me to expose them all on the front end. Whether or not this is the most efficient way of doing things I do not know, but I'd like to know if you have any idea 😄

@chenzhendong
Copy link

Case incensitive query is a critical feature

  1. Standard GraphQL demo server support case incesitive query by _contains.
  2. User inputs are always messy, wihtut ambigous match, it is hard for developer implement some features.
    Please consider adding it as eariler as possible.

@ZenSoftware
Copy link

ZenSoftware commented Jun 23, 2019

I've had to circumvent this by creating an additional field that my resolver copies and transforms to lowercase. I then do queries over that field utilizing a search parameter that is transformed to lowercase as well. This approach is a bit of a pain to maintain, and is error prone. It is possible to have stale data if you forget to update the extra field during mutations.

Case insensitive querying would solve all of these issues. This feature is at the top of my wish list.

Though, if we are going to dream about features... being able to to do something similar to SQL WHERE LIKE would open up so many doors. Though I understand that dealing with character encodings is a developers worst nightmare. Prisma was designed to be database agnostic. Doing complex string queries over a diverse set of character encodings may not have a solution.

@AndreiBacescu
Copy link

Hello everyone!
What about using raw queries? I think is the best solution for now.

@debianmaster
Copy link

facing same issue, any updates on this?

@AshkanHovold
Copy link

We just had the same problem in our app that uses GraphQL with Apollo and Neo4j. We will be writing custom queries for our search queries to get around this.

@ericauv
Copy link

ericauv commented Sep 26, 2019

Any update on when this will be available?

@frandiox
Copy link
Contributor

As mentioned before, it works correctly in demo servers with MySQL but doesn't in Postgres.

@schickling Will this be considered as a bug to be fixed in Prisma v1 under maintenance mode?

@debianmaster
Copy link

debianmaster commented Oct 17, 2019

we had to all kinds of hacks (raw queries) to get this case sensitive search working.

@nealoke
Copy link

nealoke commented Oct 25, 2019

Sees this issue, dies internally

Prisma is great and thanks for the hard work but this seems a very needed functionality 😢

@debianmaster
Copy link

not complaining, but we are thinking to get away from prisma as this needs a lot of hacks for our code. i wish there was a workaround.

@sapkra
Copy link
Contributor Author

sapkra commented Oct 26, 2019

@schickling Do you have an update on this topic because the link you've provided to the API redesign for prisma 2 is not available anymore and this feature is still not implemented in prisma 2?

@omarragi
Copy link

Im using prisma with mongo connector.
Is it possible to use mongoose is case insensitive query. ? Would that be a solution ?

@williamkwao
Copy link

This feature is really needed. I don’t mind taking a stab and making a or for this if the Prisma team is willing

@justicejoe
Copy link

Any idea on this ? Is it work now ?

@williamluke4
Copy link

@williamkwao If you have a go at it, I'll help get it reviewed and merged

@wisteria-hill-technologies
Copy link

wisteria-hill-technologies commented Dec 7, 2019

It has been more than 1 year since this thread was created but I see no clear solution from Prisma...
As debianmaster said, it is very disappointing...

I have many things related to my items I need to search case-insensitively - Items with Category, User, ProgressRecords and its Tally ,etc.
It is not practical for me to create and manage duplicates of everything in lowercase in my case.

I am now trying to use rawAccess option (I am using Postgres for databse). However, I found that all the relationships are managed solely on mapping tables in database without any indexing in each object tables due to the prisma database structure.
To get all the things in relationship to my item (before making WHERE query), I discovered that I have to make a complicated sql query (from my SQL novice point of view) using a series of 'LEFT JOIN' with all individual tables and mapping tables as organised by Prisma.
This is do-able, but this defeats the whole purpose of Prisma....not to access database directly. But, there is no other way around for me at this point...

Also, I have to be very careful accessing my database directly for search as I have to consider SQL injection issue...

@wisteria-hill-technologies
Copy link

wisteria-hill-technologies commented Dec 7, 2019

As another similar option, Ben Awad has this youtube video explaining another solution to connect database directly. https://www.youtube.com/watch?time_continue=12&v=YUjlBuI8xsU&feature=emb_logo
But, this is again another extra effort to achieve the feature Prisma is lacking at the moment.

Update (20 Dec 2019):
I ended up using this Ben Awad's solution to access the postgres instance and making sql queries directly to my database, which let me access the full capability of the postgres whereas rawAccess doesn't seem to - such as an out of box way to prevent SQL injection.
Along the way, I also discovered I cannot make query based on null value with prisma, which yet again I solved using the direct access to my database...

@justicejoe
Copy link

add it in prisma2 pls

@sapkra
Copy link
Contributor Author

sapkra commented Dec 20, 2019

FYI @herbertpimentel opened an issue for the photon project of prisma 2.
prisma/prisma-client-js#343

I think it would be great if everybody would upvote and follow/subscribe this one.

@jayktaylor
Copy link

Please add this into Prisma 1. I can't migrate to Prisma 2 yet as there are missing features that I am using.

@analoguezone
Copy link

What is the best practice for this in 2021?

@sapkra
Copy link
Contributor Author

sapkra commented Jan 15, 2021

@analoguezone To migrate to prisma 2 which now has this capability.

@svnshikhil
Copy link

svnshikhil commented May 27, 2021

Try mode
@sapkra @williamluke4

const users = await prisma.user.findMany({
  where: {
    email: {
      endsWith: "prisma.io",
      mode: "insensitive", // Default value: default
    },
  },
});

@chemicalkosek
Copy link

@svnshikhil This is an issue for Prisma 1

@esteban-gs
Copy link

Try mode
@sapkra @williamluke4

const users = await prisma.user.findMany({
  where: {
    email: {
      endsWith: "prisma.io",
      mode: "insensitive", // Default value: default
    },
  },
});

It worked for me. Thanks!

@janpio janpio closed this as completed Sep 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests