MongoQL

Gem Actions Status MIT license

Installation

Install from RubyGems by adding it to your Gemfile, then bundling.

# Gemfile
gem 'mongo_ql'
$ bundle install

Aggregation Pipeline DSL

MongoQL.compose do
  lookup  customers,
          on: customer_id == _id.to_id, 
          as: customers

  lookup  shippings, :as => shippings do |doc|
    match  order_id == doc._id, 
           status   == :shipped
  end

  where   province == "ON",
          discounts.any? { |d| d.price > 6 }

  project _id, 
          total, 
          customer  => customers.name,
          tax       => total * tax_rate,
          status    => If price <= 10, "Not Bad", "Good"

  group   customer, 
          total     => total.sum,
          total_tax => tax.sum * 5

  sort    age.dsc
end

The above aggregation DSL generates the following MongoDB pipeline

[{
  "$lookup": {
    "from": "customers",
    "as": "customers",
    "localField": "customer_id",
    "foreignField": {
      "$toString": {
        "$toObjectId": "$_id"
      }
    }
  }
}, {
  "$lookup": {
    "from": "shippings",
    "as": "shippings",
    "pipeline": [{
      "$match": {
        "$expr": {
          "$and": [{
            "$eq": ["$order_id", "$$var__id"]
          }, {
            "$eq": ["$status", "shipped"]
          }]
        }
      }
    }],
    "let": {
      "var__id": "$_id"
    }
  }
}, {
  "$match": {
    "$expr": {
      "$eq": ["$province", "ON"]
    }
  }
}, {
  "$project": {
    "_id": 1,
    "total": 1,
    "customer": "customers",
    "tax": {
      "$multiply": ["$total", "$tax_rate"]
    }
  }
}, {
  "$group": {
    "_id": "$customer",
    "total": {
      "$sum": "$total"
    },
    "total_tax": {
      "$multiply": [{
        "$sum": "$tax"
      }, 5]
    }
  }
}, {
  "$sort": {
    "age": -1
  }
}]