1 minute read

🚨 Spring Data MongoDB Gotcha That Cost Us Performance!

If you’re using Spring Data MongoDB with ExampleMatcher, here’s a performance trap that can silently degrade your application’s query performance — and it caught us off-guard.


🔍 The Problem

We were using ExampleMatcher in a Spring Data query like this:

ExampleMatcher.matching()
    .withStringMatcher(StringMatcher.EXACT)

We expected it to generate a direct MongoDB match:

{ "someField": "someValue" }

But what it actually generated under the hood was:

{ "someField": { "$regex": "^someValue$" } }

This means StringMatcher.EXACT performs a regular expression match, not a literal equality.


🐢 Why This Hurt Performance

At smaller dataset sizes, the difference went unnoticed. But as our collection grew into hundreds of thousands of documents, we began experiencing:

  • Increased query latency
  • Read timeouts
  • Poor index utilization

MongoDB was not using indexes effectively because regex queries don’t match equality-based indexes. This led to expensive collection scans.


📚 What We Learned

After analyzing query patterns in AWS Performance Insights, enabling MongoDB’s explain(), and reviewing the Spring Data documentation, we discovered this key detail:

🔴 StringMatcher.EXACT does not perform a true equality comparison. It uses a regex match with ^ and $ boundaries — which is slower and non-index-friendly.


✅ The Fix

To perform true equality matching and enable MongoDB to use indexes, we switched to:

ExampleMatcher.matching()
    .withStringMatcher(StringMatcher.DEFAULT)

This lets Spring Data generate a plain field-value query:

{ "someField": "someValue" }

Which does use indexes and perform optimally.


⚡ The Result

After making the change, we saw:

  • ✅ Significant reduction in query response time
  • ✅ No more read timeouts
  • ✅ Indexes being hit correctly
  • ✅ Reduced database load

💡 Takeaway

If you’re using ExampleMatcher in Spring Data MongoDB:

  • Don’t assume StringMatcher.EXACT means “exact match.”
  • It’s actually a regex matcher (^value$), which can cripple performance at scale.
  • Use StringMatcher.DEFAULT for true equality and index-friendly queries.

🛡️ Bonus Tip

Always test generated queries with:

db.collection.find({ someField: "someValue" }).explain("executionStats");

Verify that indexes are being used, and avoid abstraction surprises by profiling your queries early — not when you’re already in production.


Have you run into similar issues with Spring Data or MongoDB? Share your experience — let’s help others avoid these hidden pitfalls!