mongo-java-server icon indicating copy to clipboard operation
mongo-java-server copied to clipboard

Unknown top level operator: $where

Open mantasmatuzas opened this issue 4 years ago • 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)

mantasmatuzas avatar Dec 23 '20 12:12 mantasmatuzas

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?

bwaldvogel avatar Dec 23 '20 22:12 bwaldvogel

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?

mantasmatuzas avatar Dec 28 '20 13:12 mantasmatuzas

Could you point me to the solution that Fongo uses?

bwaldvogel avatar Dec 29 '20 12:12 bwaldvogel

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

mantasmatuzas avatar Dec 29 '20 12:12 mantasmatuzas

Is this somehow considered for implementation?

zpapez avatar Nov 22 '21 17:11 zpapez

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

bwaldvogel avatar Nov 23 '21 08:11 bwaldvogel