/casbah-core/src/main/scala/map_reduce/MapReduceCommand.scala

http://github.com/mongodb/casbah · Scala · 136 lines · 69 code · 25 blank · 42 comment · 0 complexity · 1674894daea2d18471d87fc5c70d10df MD5 · raw file

  1. /**
  2. * Copyright (c) 2010 MongoDB, Inc. <http://mongodb.com>
  3. * Copyright (c) 2009, 2010 Novus Partners, Inc. <http://novus.com>
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. * For questions and comments about this product, please see the project page at:
  18. *
  19. * http://github.com/mongodb/casbah
  20. *
  21. */
  22. package com.mongodb.casbah
  23. package map_reduce
  24. import scala.concurrent.duration.Duration
  25. import com.mongodb.casbah.Imports._
  26. class MapReduceException(msg: String) extends MongoException("MongoDB Map/Reduce Error: " + msg)
  27. trait MapReduceOutputTarget
  28. case class MapReduceStandardOutput(collection: String) extends MapReduceOutputTarget
  29. case class MapReduceMergeOutput(collection: String) extends MapReduceOutputTarget
  30. case class MapReduceReduceOutput(collection: String) extends MapReduceOutputTarget
  31. case object MapReduceInlineOutput extends MapReduceOutputTarget
  32. /**
  33. * Case class for invoking MongoDB mapReduces.
  34. *
  35. * This wrapper class is used in it's place, and passed directly to a db.runCommand call.
  36. *
  37. * @see <a href="http://www.mongodb.org/display/DOCS/MapReduce">The MongoDB Map/Reduce Documentation</a>
  38. *
  39. * @param input the collection name to run the map reduce on
  40. * @param map the map function (JSFunction is just a type alias for String)
  41. * @param reduce the reduce function (JSFunction is just a type alias for String)
  42. * @param output (optional) the location of the result of the map-reduce operation, defaults to inline.
  43. * You can output to a collection, output to a collection with an action, or output inline.
  44. * @param query (optional) the selection criteria for the documents input to the map function.
  45. * @param sort (optional) the input documents, useful for optimization.
  46. * @param limit (optional) the maximum number of documents to return from the collection before map reduce
  47. * @param finalizeFunction (optional) the finalize function (JSFunction is just a type alias for String)
  48. * @param jsScope (optional) global variables that are accessible in the map, reduce and finalize functions
  49. * @param verbose (optional) include the timing information in the result information
  50. * @param maxTime (optional) the maximum duration that the server will allow this operation to execute before killing it
  51. */
  52. case class MapReduceCommand protected[mongodb] (input: String = "", map: JSFunction = "", reduce: JSFunction = "",
  53. output: MapReduceOutputTarget = MapReduceInlineOutput,
  54. query: Option[DBObject] = None, sort: Option[DBObject] = None,
  55. limit: Option[Int] = None, finalizeFunction: Option[JSFunction] = None,
  56. jsScope: Option[DBObject] = None, verbose: Boolean = false,
  57. maxTime: Option[Duration] = None) {
  58. // scalastyle:off null cyclomatic.complexity method.length
  59. def toDBObject: DBObject = {
  60. val dataObj = MongoDBObject.newBuilder
  61. input match {
  62. case "" => throw new MapReduceException("input must be defined.")
  63. case null => throw new MapReduceException("input must be defined.")
  64. case other => dataObj += "mapreduce" -> input
  65. }
  66. map match {
  67. case "" => throw new MapReduceException("map must be defined.")
  68. case null => throw new MapReduceException("map must be defined.")
  69. case other => dataObj += "map" -> map.toString
  70. }
  71. reduce match {
  72. case "" => throw new MapReduceException("reduce must be defined.")
  73. case null => throw new MapReduceException("reduce must be defined.")
  74. case other => dataObj += "reduce" -> reduce.toString
  75. }
  76. dataObj += "verbose" -> verbose
  77. dataObj += "out" -> (output match {
  78. case MapReduceStandardOutput(coll: String) => coll
  79. case MapReduceMergeOutput(coll: String) => MongoDBObject("merge" -> coll)
  80. case MapReduceReduceOutput(coll: String) => MongoDBObject("reduce" -> coll)
  81. case MapReduceInlineOutput => MongoDBObject("inline" -> true)
  82. case other => throw new IllegalArgumentException("Invalid Output Type '%s'".format(other))
  83. })
  84. query match {
  85. case Some(q) => dataObj += "query" -> q
  86. case None => {}
  87. }
  88. sort match {
  89. case Some(s) => dataObj += "sort" -> s
  90. case None => {}
  91. }
  92. limit match {
  93. case Some(i) => dataObj += "limit" -> i
  94. case None => {}
  95. }
  96. finalizeFunction match {
  97. case Some(fF) => dataObj += "finalize" -> fF.toString
  98. case None => {}
  99. }
  100. jsScope match {
  101. case Some(s) => dataObj += "scope" -> s
  102. case None => {}
  103. }
  104. maxTime match {
  105. case Some(mD) => dataObj += "maxTimeMS" -> mD.toMillis
  106. case None => {}
  107. }
  108. dataObj.result()
  109. }
  110. override def toString: String = toDBObject.toString
  111. }