Using Atlas Search with Java not working

Hi, I’d like to use Atlas Search in Java.

I created a working query in Compass, and exported its Java code.

AggregateIterable<Document> result = collection.aggregate(Arrays
        .asList(eq("$search",
            eq("compound",
                eq("should",
                    Arrays.asList(
                        eq("text",
                            and(
                                eq("query", line),
                                eq("path", "title"),
                                eq("fuzzy", eq("maxEdits", 1L)),
                                eq("score", eq("boost", eq("value", 2L))))),
                        eq("text",
                            and(
                                eq("query", line),
                                eq("path", "ausschreibungsText"),
                                eq("fuzzy", eq("maxEdits", 1L)),
                                eq("score", eq("boost", eq("value", 1L))))),
                        eq("text",
                            and(
                                eq("query", line),
                                eq("path", "artikelnummerHersteller"),
                                eq("score", eq("boost", eq("value", 4L))))))))),
            limit(5),
            project(
                fields(
                    excludeId(),
                    include("title", "ausschreibungsText", "artikelnummerHersteller", "netPrice", "brutoPrice", "basismengenEinheit"),
                    computed("score", eq("$meta", "searchScore"))))));

    StreamSupport.stream(result.spliterator(), false)
        .peek(a -> LOG.info("result: {}", a))
        .collect(Collectors.toList());

Exception I am getting is:

com.mongodb.MongoCommandException: Command failed with error 8 (UnknownError): ‘Remote error from mongot :: caused by :: “path” is required (from “compound.should[0].text”)’ on server cluster0-shard-00-01.43pre.mongodb.net:27017. The full response is {“operationTime”: {"$timestamp": {“t”: 1613647388, “i”: 2}}, “ok”: 0.0, “errmsg”: “Remote error from mongot :: caused by :: “path” is required (from “compound.should[0].text”)”, “code”: 8, “codeName”: “UnknownError”, “$clusterTime”: {“clusterTime”: {"$timestamp": {“t”: 1613647388, “i”: 2}}, “signature”: {“hash”: {"$binary": {“base64”: “XcTWq9PN6XA+VigM2gDaifLd+9g=”, “subType”: “00”}}, “keyId”: 6928397309239623682}}}
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:302) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:258) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:500) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:71) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:224) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:202) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:118) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:110) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:343) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:334) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommandWithConnection(CommandOperationHelper.java:220) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper$5.call(CommandOperationHelper.java:206) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:462) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:203) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.AggregateOperationImpl.execute(AggregateOperationImpl.java:189) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.AggregateOperation.execute(AggregateOperation.java:296) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.internal.operation.AggregateOperation.execute(AggregateOperation.java:41) ~[mongodb-driver-core-4.0.5.jar:na]
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:190) ~[mongodb-driver-sync-4.0.5.jar:na]
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:135) ~[mongodb-driver-sync-4.0.5.jar:na]
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92) ~[mongodb-driver-sync-4.0.5.jar:na]
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:39) ~[mongodb-driver-sync-4.0.5.jar:na]
at java.base/java.lang.Iterable.spliterator(Iterable.java:101) ~[na:na]

So message is “path” is required (from “compound.should[0].text”)’ but I am providing this path.
What am I doing wrong here?

Marco, I believe this issue has to do with improperly formatted BSON. I am looking into your precise issue. In the meantime, you can follow this related JIRA.

1 Like

Thanks Mark, please let me know, since I am blocked by this.

Hello @Marco_Dell_Anna, meanwhile if you want to, you can try this approach to execute the aggregation query in Java:

Thanks @Prasad_Saya, using native query is bypassing the problem.
Now I got a List; since I am using Spring Data MongoDB, do you know what is the recommended approach to transform a Document into a POJO?

Hello @Marco_Dell_Anna, Spring Data MongoDB has its own APIs to work with aggregation queries. You can use MongoOperations (its implementation MongoTemplate class) or MongoRepository to build your aggregation query. For example, using MongoTemplate#Aggregate method (See MongoTemplate APIdocs) you can return the output of your aggregation as a POJO types instead of the Document class.

Also, see this post solves an aggregation using Spring Data MongoDB’'s MongoRepository API: Compass pipeline export to Java not producing same results

Thanks @Prasad_Saya, I am trying to create the query in the Spring Data MongoDB way (as in https://stackoverflow.com/questions/39445305/how-to-do-this-aggregation-in-spring-data-mongo-db), but I still need to use the “fuzzy” and “boost” functionalities provided by Atlas Search. Is it possible to do it?
If not I will need to use native query and I will need another way to create the POJOs, right?

I don’t see the API for the $search pipeline stage in the MongoTemplate#Aggregate methods. I don’t know if Spring Data supports Atlas Search (did not find anything online, yet).

I think, yes. You need some routine to transform the Document class to a POJO ( a method to extract fields from the Document class and map them to a POJO class).

Hi Marco,

thanks for bringing that issue up! It was fixed in the new Compass 1.26.0 Beta that we published. It will generate the Java Code for aggregation pipelines without the fluent API for now. We are working on providing the fluent API for aggregation pipelines with all the different stages as soon as possible.

You should also be able to generate a working Java aggregation pipeline in previous versions of Compass by disabling the “Use Builders” checkbox in the “Export Pipeline to Language” dialog.

Let me know if that helps and sorry for the inconvenience!
Michael

1 Like

Spring Data does not yet support $search pipeline natively, but we could see support for it soon.

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.