bwaldvogel/mongo-java-server

Unknown top level operator: $where

mantasmatuzas opened this issue · 6 comments

Firstly, I want to thank for such a wonderful project. Unfortunately, our team gets this error on 1.36 version. Is it possible to fix this?

Stacktrace:

14:25:40.107 [mongo-server-worker2] ERROR d.b.m.wire.MongoWireProtocolHandler - failed to handle query MongoQuery(header: MessageHeader(request: 1794, responseTo: 0, length: 156), collection: test.XXX, query: {"$orderby" : {"name" : 1}, "$query" : {"$or" : [ { "$where" : "\"\\Q\\E\" == null" }, { "name" : "{\"$regex\" : \"\\\\Q\\\\E\", \"$options\" : \"i\"}" } ]}}, returnFieldSelector: null)
de.bwaldvogel.mongo.exception.BadValueException: [Error 2] unknown top level operator: $where
	at de.bwaldvogel.mongo.backend.DefaultQueryMatcher.checkMatch(DefaultQueryMatcher.java:121)
	at de.bwaldvogel.mongo.backend.DefaultQueryMatcher.checkMatch(DefaultQueryMatcher.java:97)
	at de.bwaldvogel.mongo.backend.DefaultQueryMatcher.matches(DefaultQueryMatcher.java:38)
	at de.bwaldvogel.mongo.backend.DefaultQueryMatcher.checkMatch(DefaultQueryMatcher.java:278)
	at de.bwaldvogel.mongo.backend.DefaultQueryMatcher.checkMatch(DefaultQueryMatcher.java:119)
	at de.bwaldvogel.mongo.backend.DefaultQueryMatcher.checkMatch(DefaultQueryMatcher.java:97)
	at de.bwaldvogel.mongo.backend.DefaultQueryMatcher.matches(DefaultQueryMatcher.java:38)
	at de.bwaldvogel.mongo.backend.AbstractMongoCollection.documentMatchesQuery(AbstractMongoCollection.java:56)
	at de.bwaldvogel.mongo.backend.AbstractMongoCollection.lambda$matchDocumentsFromStream$0(AbstractMongoCollection.java:85)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:176)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at de.bwaldvogel.mongo.backend.AbstractMongoCollection.matchDocumentsFromStream(AbstractMongoCollection.java:104)
	at de.bwaldvogel.mongo.backend.AbstractMongoCollection.matchDocumentsFromStream(AbstractMongoCollection.java:77)
	at de.bwaldvogel.mongo.backend.memory.MemoryCollection.matchDocuments(MemoryCollection.java:60)
	at de.bwaldvogel.mongo.backend.AbstractMongoCollection.queryDocuments(AbstractMongoCollection.java:68)
	at de.bwaldvogel.mongo.backend.AbstractMongoCollection.handleQuery(AbstractMongoCollection.java:450)
	at de.bwaldvogel.mongo.backend.AbstractSynchronizedMongoCollection.handleQuery(AbstractSynchronizedMongoCollection.java:29)
	at de.bwaldvogel.mongo.MongoCollection.lambda$handleQueryAsync$0(MongoCollection.java:72)
	at de.bwaldvogel.mongo.util.FutureUtils.wrap(FutureUtils.java:9)
	at de.bwaldvogel.mongo.MongoCollection.handleQueryAsync(MongoCollection.java:72)
	at de.bwaldvogel.mongo.backend.AbstractMongoDatabase.handleQueryAsync(AbstractMongoDatabase.java:687)
	at de.bwaldvogel.mongo.backend.AbstractMongoBackend.handleQueryAsync(AbstractMongoBackend.java:392)
	at de.bwaldvogel.mongo.wire.MongoDatabaseHandler.handleQueryAsync(MongoDatabaseHandler.java:125)
	at de.bwaldvogel.mongo.wire.MongoDatabaseHandler.channelRead0(MongoDatabaseHandler.java:73)
	at de.bwaldvogel.mongo.wire.MongoDatabaseHandler.channelRead0(MongoDatabaseHandler.java:34)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at java.base/java.lang.Thread.run(Thread.java:834)

Hm, I’m not sure if this is easily possible to add. If I understood it correctly, the $where operator would basically require to execute a Javascript expression?

In my case, the usage of this operator looks like this:

@Query("{$or : [{$where : '\"?0\" == null'}, {'name' : {$regex: ?0, $options: 'i'}}]}")
List<Group> findGroupsLike(String name, Sort sort);

As I see in Mongo documentation, Javascript should be passed to $where clause so probably you are right.
Strangely, but with Fongo it worked (we used it previously). So maybe there would be opportunity to reuse their solution?

Could you point me to the solution that Fongo uses?

Could you point me to the solution that Fongo uses?

Check here

As I see they use Mozilla Rhino library, an Java implementation of JavaScript

Is this somehow considered for implementation?

Unfortunately I won’t be able to implement this any time soon by myself but I’m happy to receive a pull request.