ReactiveMongo常用功能

时间:2016-08-16 15:17:17

标签: scala reactivemongo play-reactivemongo

我有几个这样的功能:

  import reactivemongo.play.json.collection.JSONCollection

  def quotesFuture: Future[JSONCollection] = database.map(_.collection[JSONCollection]("quotes"))

 1:  def getByAuthor(author: String) = Action.async {
 2:    quotesFuture.flatMap{ quotes =>
 3:      quotes
 4:        .find(obj("author" -> author))
 5:        .cursor[JsObject](ReadPreference.primary)
 6:        .collect[List](maxQuotes)
 7:        .map(q => Ok(Json.toJson(q)))
 8:    }
 9:  }
10:
11:  def search(term: String) = Action.async {
12:    quotesFuture.flatMap{ quotes =>
13:      quotes
14:        .find(obj("$text" -> obj("$search" -> term)), textScore)
15:        .sort(textScore)
16:        .cursor[JsObject](ReadPreference.primary)
17:        .collect[List](maxQuotes)
18:        .map(q => Ok(Json.toJson(q)))
19:    }
20:  }

但是有很多重复;唯一改变的是查找和排序,所以我想重构如下:

100:  def getByAuthor(author: String) = getList { quotes =>
101:    quotes
102:      .find(obj("author" -> author))
103:  }
104:
105:  def search(term: String) = getList { quotes =>
106:    quotes
107:      .find(obj("$text" -> obj("$search" -> term)), textScore)
108:      .sort(textScore)
109:  }
110:
111:  def getList(query: (JSONCollection) => ???) = Action.async {
112:    quotesFuture.flatMap{ quotes =>
113:      query(quotes)
114:        .cursor[JsObject](ReadPreference.primary)
115:        .collect[List](maxQuotes)
116:        .map(q => Ok(Json.toJson(q)))
117:    }
118:  }

问题是第111行的???应该是什么?

当要求IntelliJ从第14-15行提取方法时,它会创建以下

  def tempdef(term: String, quotes: JSONCollection): GenericQueryBuilder[quotes.pack.type]#Self = {
    quotes
      .find(obj("$text" -> obj("$search" -> term)), textScore)
      .sort(textScore)
  }

IntelliJ提出的结果类型非常可怕。因此,第111行中的???应为GenericQueryBuilder[quotes.pack.type]#Self,但它取决于变量quotes。我应该用???代替什么才能使其发挥作用?

使用IntelliJ,我看到quotes.pack指的是:

case class JSONCollection(...) {...
  val pack = JSONSerializationPack
}

我尝试用???替换第111行中的JSONSerializationPack.type,然后编译并运行。

但是,查看JSONCollection的实现细节是作弊的,如果JSONCollection的实现发生更改,这可能会停止工作。

那么,第111行的???应该是什么?

否则,您是否看到在此示例中删除代码重复的更简单方法?

1 个答案:

答案 0 :(得分:0)

我建议您getByAuthorsearch返回Cursor[JsObject],这样可以让他们拥有不同的ReadPreference,并使用非依赖类型(与查询构建器依赖于集合的基础序列化包,IDE无法理解这一点。

import reactivemongo.api.Cursor

def getByAuthor(author: String): Cursor[JsObject] = ???

def search(term: String): Cursor[JsObject] = ???

def getList(cursor: JSONCollection => Cursor[JsObject] = Action.async {
  quotesFuture.flatMap { quotes =>
    val c: Cursor[JsObject] = cursor(quotes)
    ???
  }