ReactiveMongo $in operator returns zero elements

reactivemongo find projection
scala mongodb orm
mongodb scala synchronous
mongodb reactive streams
reactivemongo count
reactivemongo operations example

Having issues using the $in operator in a ReactiveMongo 0.11 query. For some reason the query returns zero documents, although I can confirm that the IDs exist. So I assume I'm not structuring this properly.

Here's my query:

val query = BSONDocument("userId" -> userId, "convoId" -> BSONDocument("$in" -> BSONArray(convoIds)))
collection.find(query).cursor[ChatDesc](ReadPreference.primaryPreferred).collect[List]()

I construct my BSONArray by applying a list:

BSONArray(List(id1, id2, ...))

Here are the IDs being used in the query:

List(5594ee9f02fb36b06e2925b155ea043bfb006c5a6a8436be, 552c784430a54cf55e07190955ea043bfb006c5a6a8436be, 55af435c9524018461f750ec55ea043bfb006c5a6a8436be...)

If I leave out the $in operator and manually check every convoIds field, I can confirm that the 3rd ID above 55af435c9524018461f750ec55ea043bfb006c5a6a8436be is in fact present many times in the collection. Additionally, the other objects meet the criteria for the userId field.

My only other guess is I need to create some sort of MongoDB secondary index on the fields?

Not sure what I'm doing wrong. Thanks!

Update

I've narrowed the problem to how I'm applying the BSONArray. If I manually paste one of the IDs like this, BSONArray("thestringID"), and run the query it is successful. Seems peculiar since I thought List was a descendant of Traversable?

Please indicate the versions you are using.

If you have a look a the documentation, you can see the BSONArray can be created from either Traversable[BSONValue] or from Producer[BSONValue].

It seems you're list is a List[String], which is Traversable but not Traversable[BSONValue], which means it tries apply the former constructor with Producer[BSONValue]*.

Indeed, there is an instance of the type class Producer[BSONValue] for List[String], as there is one for List as soon as the element type is also provided one (which is the case for String). Such producer creates a BSONArray itself.

So the call BSONArray(List("id1","id1")) results in BSONArray(BSONArray("id1","id2")), which valid, but has no sense for the query.

Find Documents, Queries are performed quite the same way as in the MongoDB Shell. collect[​List]() which returns a future list of documents; enumerate() which returns an  Reactive Scala Driver for MongoDB. Asynchronous & Non-Blocking. ReactiveMongo 0.20.10 – Release details. What’s new? The documentation is available online, and its code samples are compiled to make sure it’s up-to-date.

You should not use BSONArray for List, it's enough to place List in BSONDocument without anything:

val query = BSONDocument("userId" -> userId, "convoId" -> BSONDocument("$in" -> convoIds))

or in Play JSON library:

val query = Json.obj("convoId" -> Json.obj("$in" -> convoIds))

Aggregation Framework, $geoNear : Returns an ordered stream of documents based on the proximity to a The Avg operator can be used instead of AvgField , to use an expression in BSONCollection, max: Int, offset: Int = 0): Future[List[StateStats]] = { import col. Returns true if elements are equal. More bool operator!= (const BSONElement &r) const Returns true if elements are unequal. More int woCompare (const BSONElement &e, bool considerFieldName=true) const Well ordered comparison. More const char * rawdata const int getGtLtOp (int def=0) const 0 == Equality, just not defined yet

I had to iterate through the list since the BSONArray doesn't seem to support scala's native List.

var idFilter = BSONArray()
matchIds.foreach( id => idFilter = idFilter ++ id)
val query = BSONDocument("userId" -> userId, "convoId" -> BSONDocument("$in" -> idFilter))

Release details, Add credentials in the MongoConnectionOptions; Netty native. BSON library The next release will be 1.0.0. The impatient can If true, returns only the index keys in the resulting documents. The $slice operator is also supported as bellow. Reactive Scala Driver for MongoDB. Asynchronous & Non-Blocking. Streaming. Instead of accumulating documents in memory, they can be processed as a stream, using a reactive Cursor. ReactiveMongo can be used with several streaming frameworks: Play Iteratees, Akka Streams, or with custom processors using foldWhile (and the other similar operations).

Streaming, Instead of accumulating documents in memory, they can be processed as a stream, using a It will eventually return the final value of the sink, which is a Seq in our case. val cumulateAge: Sink[BSONDocument, Future[(Int, Int)]] = Sink.fold(0 -> 0) { case The run method on Enumerator has an operator alias, |​>>> . So we  BSONElement represents an "element" in a BSONObj. So for the object { a : 3, b : "abc" }, 'a : 3' is the first element (key+value). The BSONElement object points into the BSONObj's data. Thus the BSONObj must stay in scope for the life of the BSONElement. Member Function Documentation

ReactiveMongo API 0.20, In the MongoDB shell, such aggregation is written as bellow (see the example). result, and must not be exposed as public return type in your application/API. Group the intermediate documents by the _id.state field (i.e. the state field inside The operators available to define an aggregation pipeline are documented in  Operand Description <start> An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. <end> An integer that specifies the exclusive upper limit of the sequence.

ReactiveMongo API 0.20, Instead of accumulating documents in memory like in the two previous examples, we can process them as a stream. The method cursor.enumerate() returns an Enumerator[T] . In this The run method on Enumerator has an operator alias, |>​>> . getOrElse(0) (cumulatedAge + age, n + 1) } val cumulated: Future[(Int, Int)]​  Find the nonzero elements in a 4-by-2-by-3 array. Specify two outputs, row and col, to return the row and column subscripts of the nonzero elements. When the input is a multidimensional array (N > 2), find returns col as a linear index over the N-1 trailing dimensions of X.

Comments
  • Please indicate the versions you are using. If you have a look a the doc, you can see the
  • I added the version to my question. This answer might be more helpful if you can reference the specific API doc for Producer or give an example. I am, of course, appreciative if there's a cleaner and better way to fix the problem.
  • As for other types, the doc is in the online Scaladoc.