1

I am using the MongoDB Java client to query data:

    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongodb-driver</artifactId>
        <version>3.5.0</version>
    </dependency>

The server version is 3.4.10.

When using the MongoDB shell, I can successfully query using:

db.c1.find(
    { title: { $in: [/test/,/demo/] } },
    { title:1 }
)

But when using the Java driver it does not work. For example:

List<String> keywords = new ArrayList<>();
keywords.add("/test/");
keywords.add("/demo/");
Document titleRegEx = new Document("$in", keywords);

Document filter = new Document("title", titleRegEx);

Document firstDoc = coll.find(filter).first();

logger.info("firstDoc: {}", firstDoc);

Please help me out.

0

1 Answer 1

3

If you profile the MongoDB calls you'll see that this 'find statement' ...

List<String> keywords = new ArrayList<>();
keywords.add("/test/");
keywords.add("/demo/");
Document titleRegEx = new Document("$in", keywords);

Document filter = new Document("title", titleRegEx);

Document firstDoc = coll.find(filter).first();

... causes the following filter to be submitted to MongoDB:

filter: { title: { $in: [ "/test/", "/demo/" ] } } }

Note the value of the $in document; instead of $in: [/test/,/demo/] it is: $in: [ "/test/", "/demo/" ]. So, it is performing exact string matches on "/test/" and "/demo/" rather than regex matches. This explains why this 'find statement' returns nothing.

You engage a regex search when using the Java driver like so:

Filters.regex("title", "test")

The MongoDB Java driver does not allow you to supply a collection of Bson instances for $in so if you want to search for documents which match one of the elements in this 'in' list: /test/, /demo/ then you have to form an OR query. For example:

 Bson filter = Filters.or(Filters.regex("title", "test"), Filters.regex("title", "demo"));

 FindIterable<Document> documents = collection.find(filter);

If you profile the MongoDB calls you'll see that the above code causes the following 'find statement' to be executed on MongoDB:

find { find: "posts", filter: { $or: [ { title: /test/ }, { title: /demo/ } ] } }

This is functionally equivalent to the command you showed in your question.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks to your replay, that's a right way~

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.