Search code examples
c#.netmongodbgraphqlhotchocolate

MongoDB case insensitive "contains" operation, is it possible?


Here's my situation :

In my MongoDB Database, I have a list of objects. Using an GraphQL API, I can search them using a filter. This filter creates a 'contains' filter input with my value, 'bar' for example. However, when the request is finished, I only get object that exactly matches the 'bar' sequences, even if I have other variants of the 'bar' sequence 'Bar, BAR, and so on...).

I've tried many implementations in my C# project (Custom Filtering, Custom Convention, ...) but nothing seems to be working.

here's an example of the request :

query SEARCH{
  search (            
    id: {
      wksUuid:"id1",
      prjUuid:"id2",
      fileUuid:"id3",
      fileVersion:"id4",
      stepLine:"id5"
    }        
  ) 
  {             
    foo
    (
      first: 30 
      after: null, 
      order: null, 
      where: {
        name:{
          contains: "bar"
        }
      }
    ) {                 
      pageInfo {                     
        hasNextPage                     
        endCursor                 
      }                 
      nodes {                                         
        name                               
      }             
    }         
  }     
}

This request is treated as such in my package :

public async getFooItems(id: id, first?: string, cursor?: string, order?: any[], filters?: any): Promise<ResponseAPICall<any>> {
    const stringifiedId: string = JSON.stringify(id)?.replace(/"([^"]+)":/g, '$1:')
    
    const query: string = this.SEARCH.replace('$id', stringifiedId)
                                .replace('$cursor', cursor ? `"${cursor}"` : 'null')
                                .replace('$first', first ? first : 'null')
                                .replace('$order', (order && order?.length > 0) ? JSON.stringify(order)?.replace(/['"]+/g, '') : 'null')
                                .replace('$filters', filters ? JSON.stringify(filters)?.replace(/\"(\w+)\"\:/g, "$1:")?.replace(/\"([^\"]+)\":/g, '$1:') : 'null')
    const body: {query: string} = { query: query }
    const response: ResponseAPICall<any> = await this.httpRqs.post(this.apiUrl, body)

    return response
}

Is it even possible, using HotChocolate, MongoDB.Driver to apply a case insentive argument on the 'Contains' operation ?

  • Custom String Filter (C#) : Implementation of a custom filter to override the contain operation, didn't work.
  • Custom FilterConvention : Custom FilterConvention to override the current convention, Failed
  • Followed Extending Filtering, didn't work (the contain operation wasn't override on my request)
  • Tried to edit the filter before the request is sent, failed (can't convert a StringType to a RegexType)

Edit : Here's how my object is resolved inside GraphQL, and I did try to extend said resolver to try and cofigure operations, but didn't succeed.

public class Foo: ObjectType<Foo>
{
    protected override void Configure(IObjectTypeDescriptor<Foo> descriptor)
    {
        descriptor.Field(_ => _.Id);
        descriptor.Field(_ => _.History);

        descriptor.Field(_ => _.Name);
        descriptor.Field(_ => _.IfcClassName);
        descriptor.Field(_ => _.IniesClassifCode);
        descriptor.Field(_ => _.Contributor);
        descriptor.Field(_ => _.Unit);
        descriptor.Field(_ => _.Lot);
        descriptor.Field(_ => _.BundleId);
        descriptor.Field(_ => _.RelatedContributorsId);
        descriptor.Field(_ => _.Qto);
        descriptor.Field(_ => _.RelatedEmptyComponentId);
        descriptor.Field(_ => _.InodeId);

        descriptor.Field<CbzContributorResolver>(_ => _.GetRelatedContributors(default, default))
            .Name("relatedContributors")
            .UsePaging()
            //.UseOffsetPaging()
            .UseSorting()
            .UseFiltering();
    }
}

Solution

  • Try applying i flag to make your regex case-insensitive.

    See: https://stackoverflow.com/a/10610461/5024706