object ConnHelper extends Serializable{
  lazy val jedis = new Jedis("localhost")
  lazy val mongoClient = MongoClient("mongodb://localhost:27017/recommender")
}
val ratingCollection = ConnHelper.mongoClient.getDatabase(mongoConfig.db).getCollection(MONGODB_RATING_COLLECTION)
val Existratings: Observable[Option[BsonValue]] = ratingCollection
    .find(equal("userId",1234))
    .map{
    item => item.get("productId")
    }

Dokumenty są takie

{
  "id":****,
  "userId":4567,
  "productId":12345,
  "score":5.0
}

Używam Scali i Mongo-Scala-driver 2.9.0, aby połączyć się z MongoDB i znaleźć dokumenty, w których pole „userId” jest równe 1234, następnie chcę zapisać wartość „productId” dokumentów do Array, ale zwracana wartość jest obserwowalna . Czy ktoś mógłby powiedzieć, jak zapisać wynik zapytania w tablicy? Byłbym bardzo wdzięczny.

1
Alex 31 marzec 2020, 14:45

3 odpowiedzi

Najlepsza odpowiedź

Sterownik Mongo Scala wykorzystuje Observable model, który składa się z trzech części.

Musisz zapisać obserwatora do obserwowalnego. Spójrz na przykłady.

Najszybszym rozwiązaniem jest wykonanie połączenia toFuture:

val Existratings =
      ratingCollection
      .find(equal("userId",1234))
      .map{
        item => item.get("productId")
      }.toFuture()

To zwróci Sep z BsonValues z zestawem wyników

0
EmiCareOfCell44 31 marzec 2020, 12:26

Wypróbuj metodę, która wykorzystuje strukturę Promise / Future , aby znaleźć sekwencję dokumentów pasujących do kryteriów wyszukiwania. Na przykład:

import org.mongodb.scala.bson._
def find (search_key: String, search_value: String, collection_name: String): Seq[Document] = {

    // The application will need to wait for the find operation thread to complete
    // in order to process the returned value.

    log.debug(s"Starting database find_all operation thread")

    // Set up new client connection, database, and collection
    val _client: MongoClient = MongoClient(config_client)
    val _database: MongoDatabase = _client.getDatabase(config_database)
    val collection: MongoCollection[Document] = _database.getCollection(collection_name)

    // Set up result sequence
    var result_seq : Seq[Document] = Seq.empty

    // Set up Promise container to wait for the database operation to complete
    val promise = Promise[Boolean]

    // Start insert operation thread; once the thread has finished, read resulting documents.
    collection.find(equal(search_key, search_value)).collect().subscribe((results: Seq[Document]) => {
      log.trace(s"Found operation thread completed")
      // Append found documents to the results
      result_seq = result_seq ++ results
      log.trace(s" Result sequence: $result_seq")

      promise.success(true) // set Promise container
      _client.close // close client connection to avoid memory leaks
     })


    val future = promise.future // Promise completion result
    Await.result(future, Duration.Inf) // wait for the promise completion result

    // Return document sequence
    result_seq

  }

Następnie możesz iterować przez sekwencję dokumentów i przeciągać produkty do listy (lepszej niż Array).

def read : List[String] = {

    val document_seq = Database.find("userID","1234",collection)

    // Set up an empty return map
    val return_map : mutable.Map[String, String] = mutable.Map.empty

    // Translate data from each document into Product object
    document_seq.foreach(_document => {
      return_map.put(
         _document("id").asString.getValue,
         _document("productId").asString.getValue
        )
      
    })

    // Convert values to list map and return
    return_map.values.toList
  }
1
LineDrop 2 grudzień 2020, 17:04

To może być:

val productIds = ratingCollection
    .find(equal("userId",1234))
    .map { _.get("productId") }
    .toArray
0
Philluminati 31 marzec 2020, 12:22