Scala Driver Performing Nested Push to Array

76 views
Skip to first unread message

Sinan Pehlivanoglu

unread,
Aug 12, 2018, 8:06:07 PM8/12/18
to mongodb-user
I am having a little bit of trouble properly appending to a nested array using Mongo in Scala. I have done the same operation numerous times in Node.js but for some reason I can translate it to Scala. 

Here is the main "schema": 

    case class Band(
                 _id: ObjectId,
                 name: String,
                 username: String,
                 email: String,
                 path: String,
                 tours: List[Tour],
                 merchSets: List[MerchSet],
                 facebook: Option[String],
                 twitter: Option[String],
                 youtube: Option[String],
                 instagram: Option[String],
                 website: Option[String]
               )

As you can see this definition has a List of Tours where a Tour is defined as: 

    case class Tour(_id: ObjectId,
                name: String,
                shows: List[Show],
                items: List[Item],
                region: String,
                default_merchset : Option[MerchSet]
               )

I am trying basically push an Item to the items collection, if it doesn't exist, whenever a new item is created.

Basically the end point receives a band id, a tour name and bunch of form params which is used to create and push the Item. 

GOAL: The query needs to find the correct band, and the correct tour from the corresponding tours collection and add the created item to corresponding tour.items

The way I would do this in Node.js is the following: 

    var query = {"_id": id, "tours.name": name}
    Band.findOneAndUpdate(
        query,
        {$push: {"tours.$.items": item}}
      )

But this just doesn't work in Scala. And I get no errors at all. The subscription hits the OnComplete case although nothing changes in the DB. 

Here is what I have currently: 

    val add = MongoDataBaseConnector.bands.findOneAndUpdate(and(equal("_id", id),
      equal("tours.name", tour_name)),
      push("tours.items", request.toDomain))


I have tried to $ operator in the middle but it doesn't make any difference. The documentation doesn't help either. For some reason the driver documentation is written as a basic tutorial and only hits very specific cases. 

What is the proper way to go about this? 

Wan Bachtiar

unread,
Sep 20, 2018, 3:59:28 AM9/20/18
to mongodb-user

What is the proper way to go about this?

Hi Sinan,

It’s been a while since you posted this question, have you found a solution yet ?

The following operation works as intended using MongoDB Scala driver v2.4.0 (Scala 2.12)

collection.findOneAndUpdate(equal("tours.name", "foobar"), push("tours.$.items", Item("baz"))).printResults()

And I get no errors at all. The subscription hits the OnComplete case although nothing changes in the DB.

Make sure that the query filter part actually finds a document, i.e.

and(equal("_id", id), equal("tours.name", tour_name))

You could test by executing just with a find() first, to check whether something is actually returned.

If you still have further question, please provide:

  • MongoDB Scala driver version
  • Complete, minimal, and reproducible example
  • Example documents

Regards,
Wan.

Reply all
Reply to author
Forward
0 new messages