我有一个MongoDB数据库,其中存储不同的文件,这些文件可以是png,jpg,pdf,这里有一个例子:
{
"_id" : "id of the document",
"metadata" : {
"s" : "documents",
"u" : "id of the owner",
"d" : ""
},
"filename" : "El-jugador-Fedor-Dostoyevski.pdf",
"contentType" : "application/pdf",
}
字符串
我删除了一些不相关的字段,文档的类型由contentType
字段给出,我想要的是使用Scala和ReactiveMongo获得每种类型文件的计数
我已经这样做了,但是做了三次咨询,这样:
def contentTypeStats(implicit ec: ExecutionContext): Future[ContentTypesDTO] = {
collectionFactory.collection().flatMap(collection => {
val filterDocuments = BSONDocument("metadata.s" -> BSONDocument("$ne" -> "thumbnail"))//don't want count thumbnails, only documents
val filterPNG = BSONDocument(filterDocuments, "contentType" -> "image/png")
val filterJPG = BSONDocument(filterDocuments, "contentType" -> "image/jpeg")
val filterPDF = BSONDocument(filterDocuments, "contentType" -> "application/pdf")
val countPNGFuture: Future[Long] = collection.count(Some(filterPNG))
val countJPGFuture: Future[Long] = collection.count(Some(filterJPG))
val countPDFFuture: Future[Long] = collection.count(Some(filterPDF))
for {
countPNG <- countPNGFuture
countJPG <- countJPGFuture
countPDF <- countPDFFuture
} yield {
ContentTypesDTO(
pngCount = countPNG,
jpgCount = countJPG,
pdfCount = countPDF
)
}
})
}
型
我只想用一个consult来做这件事,在MongoDB中,我是这样做的:
db.getCollection('myCollection').aggregate([
{$match: {'metadata.s': {$ne: 'thumbnail'}}},
{$group: {_id: "$contentType", count: {$sum: 1}} }
])
型
他们给了我这个:
/* 1 */
{
"_id" : "image/png",
"count" : 5.0
}
/* 2 */
{
"_id" : "application/pdf",
"count" : 9.0
}
/* 3 */
{
"_id" : "image/jpeg",
"count" : 8.0
}
型
我试着这样做:
def contentTypeStats(implicit ec: ExecutionContext): Future[ContentTypesDTO] = {
collectionFactory.collection().flatMap(collection => {
import collection.AggregationFramework._
val result: Future[Option[BSONDocument]] = collection.aggregatorContext[BSONDocument](
pipeline = List(
Match(BSONDocument("metadata.s" -> BSONDocument("$ne" -> "thumbnail"))),
Group(BSONDocument("_id" -> "$contentType"))("count" -> SumAll)
)
).prepared.cursor.headOption
result.map {
case Some(doc) =>
println(doc.getAsOpt[String]("_id"))//here always return None
ContentTypesDTO(
pngCount = doc.getAsOpt[Long]("count").getOrElse(0L),
jpgCount = doc.getAsOpt[Long]("count").getOrElse(0L),
pdfCount = doc.getAsOpt[Long]("count").getOrElse(0L)
)//all have the same number
}
})
}
型
该方法返回None
时,要求_id
和计数字段给予随机一些以前的结果(5,8,9),它应该是一种方式来访问特定计数字段的每个_id
,应该是image/png
或image/jpeg
或application/pdf
,但如果我可以得到_id
1条答案
按热度按时间23c0lvtd1#
我的解决方案中有几个问题
字符串
这里我将
_id
Map为BSONDocument
,这就是为什么a不能得到_id
,所以解决方案是以这种方式Map为BSONString
型
Group
方法总是用第一个参数创建_id
字段。第二个问题是返回结果,这里.prepared.cursor.headOption
只从创建的组中返回第一个BSONDocument。要修复的是使用reactivemongo.prepared.cursor.collect[List](-1, Cursor.FailOnError[List[BSONDocument]]())
中的Cursor类返回一个BSONDocument的列表,之后还将ContentTypesDTO
更改为仅型
并使用Map上的
result
得到一个Seq[ContentTypesDTO]
这里的最终解决方案:型
该方法返回以下内容:
型