diff --git a/error-prone-contrib/pom.xml b/error-prone-contrib/pom.xml
index 18dd0e6d78..75a31b47b3 100644
--- a/error-prone-contrib/pom.xml
+++ b/error-prone-contrib/pom.xml
@@ -176,6 +176,11 @@
mockito-core
provided
+
+ org.mongodb
+ mongodb-driver-core
+ test
+
org.reactivestreams
reactive-streams
diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsage.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsage.java
new file mode 100644
index 0000000000..77208f673e
--- /dev/null
+++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsage.java
@@ -0,0 +1,47 @@
+package tech.picnic.errorprone.bugpatterns;
+
+import static com.google.errorprone.BugPattern.LinkType.CUSTOM;
+import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
+import static com.google.errorprone.BugPattern.StandardTags.PERFORMANCE;
+import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
+import static tech.picnic.errorprone.bugpatterns.util.Documentation.BUG_PATTERNS_BASE_URL;
+
+import com.google.auto.service.AutoService;
+import com.google.errorprone.BugPattern;
+import com.google.errorprone.VisitorState;
+import com.google.errorprone.bugpatterns.BugChecker;
+import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
+import com.google.errorprone.matchers.Description;
+import com.google.errorprone.matchers.Matcher;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.MethodInvocationTree;
+
+/**
+ * A {@link BugChecker} that flags usages of MongoDB {@code $text} filter usages.
+ *
+ * @see MongoDB Text Search
+ */
+@AutoService(BugChecker.class)
+@BugPattern(
+ summary =
+ "Avoid MongoDB's `$text` filter operator, as it can trigger heavy queries and even cause the server to run out of memory",
+ link = BUG_PATTERNS_BASE_URL + "MongoDBTextFilterUsage",
+ linkType = CUSTOM,
+ severity = SUGGESTION,
+ tags = PERFORMANCE)
+public final class MongoDBTextFilterUsage extends BugChecker
+ implements MethodInvocationTreeMatcher {
+ private static final long serialVersionUID = 1L;
+ private static final Matcher MONGO_FILTERS_TEXT_METHOD =
+ staticMethod().onClass("com.mongodb.client.model.Filters").named("text");
+
+ /** Instantiates a new {@link MongoDBTextFilterUsage} instance. */
+ public MongoDBTextFilterUsage() {}
+
+ @Override
+ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
+ return MONGO_FILTERS_TEXT_METHOD.matches(tree, state)
+ ? describeMatch(tree)
+ : Description.NO_MATCH;
+ }
+}
diff --git a/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsageTest.java b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsageTest.java
new file mode 100644
index 0000000000..ea9ca288a8
--- /dev/null
+++ b/error-prone-contrib/src/test/java/tech/picnic/errorprone/bugpatterns/MongoDBTextFilterUsageTest.java
@@ -0,0 +1,26 @@
+package tech.picnic.errorprone.bugpatterns;
+
+import com.google.errorprone.CompilationTestHelper;
+import org.junit.jupiter.api.Test;
+
+final class MongoDBTextFilterUsageTest {
+ @Test
+ void identification() {
+ CompilationTestHelper.newInstance(MongoDBTextFilterUsage.class, getClass())
+ .addSourceLines(
+ "A.java",
+ "import com.mongodb.client.model.Filters;",
+ "import com.mongodb.client.model.TextSearchOptions;",
+ "",
+ "class A {",
+ " void m() {",
+ " Filters.eq(\"foo\", \"bar\");",
+ " // BUG: Diagnostic contains:",
+ " Filters.text(\"foo\");",
+ " // BUG: Diagnostic contains:",
+ " Filters.text(\"foo\", new TextSearchOptions());",
+ " }",
+ "}")
+ .doTest();
+ }
+}
diff --git a/pom.xml b/pom.xml
index b8855c75ea..265360736b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -443,6 +443,19 @@
pom
import
+
+ org.mongodb
+ mongodb-driver-core
+ 4.10.2
+
+
+
+ org.mongodb
+ bson-record-codec
+
+
+
org.slf4j
slf4j-api