我有几个这样的功能:
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行的???
应该是什么?
否则,您是否看到在此示例中删除代码重复的更简单方法?
答案 0 :(得分:0)
我建议您getByAuthor
和search
返回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)
???
}