Skip to content

Add Case insensitive search#1565

Open
mcgong720 wants to merge 2 commits intoaws:mainfrom
mcgong720:feat/case-insensitive-search
Open

Add Case insensitive search#1565
mcgong720 wants to merge 2 commits intoaws:mainfrom
mcgong720:feat/case-insensitive-search

Conversation

@mcgong720
Copy link

@mcgong720 mcgong720 commented Mar 6, 2026

Description

Add a case-insensitive search toggle to the keyword search sidebar that works across all three query engines (Gremlin, OpenCypher, SPARQL).

  • Gremlin: Uses regex() with (?i) flag for case-insensitive matching. Escapes the $ regex anchor as \$ to prevent Groovy string interpolation errors. Regex metacharacters in search terms are escaped to avoid injection.
  • OpenCypher: Wraps attribute values and search terms in toLower() for case-insensitive comparison on both partial and exact matches.
  • SPARQL: Uses regex() with "i" flag for partial matches and lcase() for exact matches.

The toggle does not apply to ID-based searches since IDs are system-generated and case-sensitivity is not meaningful.

Validation

  • Unit tests: 17 new tests added for case-insensitive search:
    • Gremlin (keywordSearchTemplate.test.ts - 6 new):
      • Case-insensitive partial match generates regex("(?i).*term.*") syntax
      • Case-insensitive exact match generates regex("(?i)^term\$") with escaped $ to prevent Groovy interpolation
      • Case-insensitive is not applied to ID-based searches (IDs use standard containing() or exact match)
      • Case-sensitive mode (toggle off) still uses standard containing() and exact string match
      • Regex metacharacters in search terms (e.g., test.com) are escaped as test\\.com in partial match
      • Regex metacharacters are escaped in exact match too (test\\.com\$)
    • OpenCypher (keywordSearchTemplate.test.ts - 5 new):
      • Case-insensitive partial match wraps both sides in toLower(): toLower(toString(v.attr)) CONTAINS toLower("term")
      • Case-insensitive exact match uses toLower(toString(v.attr)) = toLower("term")
      • Case-insensitive is not applied to ID searches (IDs use toString(id(v)) without toLower)
      • Case-sensitive mode (toggle off) uses plain v.attr CONTAINS "term" without toLower()
      • Combined test with multiple vertex types, multiple attributes, ALL_ATTRIBUTES token, limit, and offset
    • SPARQL (keywordSearchTemplate.test.ts - 3 new):
      • Case-insensitive partial match uses regex(str(?value), "term", "i") with the "i" flag
      • Case-insensitive exact match uses lcase(str(?value)) = lcase("term") for string comparison
      • Partial match remains case-insensitive even when caseInsensitive flag is false (SPARQL's contains() is inherently case-sensitive, so partial match always uses regex with "i")
    • Search Sidebar (useKeywordSearch.test.ts - 3 new):
      • caseInsensitive defaults to false for Gremlin connections
      • caseInsensitive defaults to false for OpenCypher connections
      • caseInsensitive defaults to false for SPARQL connections
  • Manual testing with Gremlin Server (air_routes sample data): Verified partial and exact match with case-insensitive toggle on/off.
  • Manual testing with JanusGraph: Loaded mixed-case test data (JFK, lax, ORD, san francisco). Verified case-insensitive search works.
  • Manual testing with BlazeGraph (SPARQL): Loaded RDF triples with mixed-case data. Verified regex("i") flag works for partial matches and lcase() works for exact matches.
  • Manual testing with Neptune: Tested all three query languages (Gremlin, OpenCypher, SPARQL). Case-insensitive search works correctly for both partial and exact matches.

Related Issues

Check List

  • I confirm that my contribution is made under the terms of the Apache 2.0 license.
  • I have run pnpm checks to ensure code compiles and meets standards.
  • I have run pnpm test to check if all tests are passing.
  • I have covered new added functionality with unit tests if necessary.
  • I have added an entry in the Changelog.md.

fix: add case-insensitive search support for keyword search

Add a case-insensitive toggle to the keyword search sidebar that works
across all three query engines (Gremlin, OpenCypher, SPARQL).

Gremlin: Uses regex with (?i) flag. Escapes the `$` anchor as `\$` to
prevent Groovy string interpolation errors. Regex metacharacters in
search terms are escaped to avoid injection.

OpenCypher: Wraps attribute values and search terms in toLower() for
case-insensitive comparison.

SPARQL: Uses regex() with "i" flag for partial matches and lcase() for
exact matches.

The toggle does not apply to ID-based searches since IDs are
system-generated and case-sensitivity is not meaningful.
@mcgong720 mcgong720 changed the title Case insensitive search Add Case insensitive search Mar 6, 2026
@kmcginnes kmcginnes self-requested a review March 6, 2026 16:26
@kmcginnes
Copy link
Collaborator

@mcgong720 Excellent. I just took a quick glance and I like it.

I have a few other things to attend to before reviewing this. So it might be a few days before I can take a closer look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants