<commit_before>Mongoid::CachedJson [![Build Status](https://secure.travis-ci.org/dblock/mongoid-cached-json.png)](http://travis-ci.org/dblock/mongoid-cached-json)
===================

Typical *as_json* definitions may involve lots of database point queries and method calls. When returning collections of objects, a single call may yield hundreds of database queries that can take seconds. This library mitigates the problem by implementing a module called *CachedJson*.

CachedJson enables returning multiple JSON formats and versions from a single class and provides some rules for returning embedded or referenced data. It then uses a scheme where fragments of JSON are cached for a particular (class, id) pair containing only the data that doesn't involve references/embedded documents. To get the full JSON for an instance, CachedJson will combine fragments of JSON from the instance with fragments representing the JSON for its references. In the best case, when all of these fragments are cached, this falls through to a few cache lookups followed by a couple Ruby hash merges to create the JSON.

Using Mongoid::CachedJson we were able to cut our JSON API average response time by about a factor of 10.

Resources
---------

* [Need Help?](http://groups.google.com/group/mongoid-cached-json)
* [Source Code](http://github.com/dblock/mongoid-cached-json)
* [Travis CI](https://secure.travis-ci.org/dblock/mongoid-cached-json)

Quickstart
----------

Add `mongoid-cached-json` to your Gemfile.

    gem "mongoid-cached-json"

Include `Mongoid::CachedJson` in your models.

``` ruby
class Gadget
  include Mongoid::CachedJson

  field :name
  field :extras

  belongs_to :widget

  json_fields \
    :name => { },
    :extras => { :properties => :public }

end

class Widget
  include Mongoid::CachedJson

  field :name
  has_many :gadgets

  json_fields \
    :name => { },
    :gadgets => { :type => :reference, :properties => :public }

end
```

Invoke `as_json`.

``` ruby
# the `:short` version of the JSON, `gadgets` not included
Widget.first.as_json

# equivalent to the above
Widget.first.as_json({ :properties => :short })

# `:public` version of the JSON, `gadgets` returned with `:short` JSON, no `:extras`
Widget.first.as_json({ :properties => :public })

# `:all` version of the JSON, `gadgets` returned with `:all` JSON, including `:extras`
Widget.first.as_json({ :properties => :all })
```

Configuration
-------------

By default `Mongoid::CachedJson` will use an instance of `ActiveSupport::Cache::MemoryStore` in a non-Rails and `Rails.cache` in a Rails environment. You can configure it to use any other cache store.

``` ruby
Mongoid::CachedJson.configure do |config|
  config.cache = ActiveSupport::Cache::FileStore.new
end
```

The default JSON version returned from `as_json` is `:unspecified`. If you wish to redefine this, set `Mongoid::CachedJson.config.default_version`.

``` ruby
Mongoid::CachedJson.configure do |config|
  config.default_version = :v2
end
```

Definining Fields
-----------------

Mongoid::CachedJson supports the following options.
<commit_msg>Typo, defining fields.<commit_after>Mongoid::CachedJson [![Build Status](https://secure.travis-ci.org/dblock/mongoid-cached-json.png)](http://travis-ci.org/dblock/mongoid-cached-json)
===================

Typical *as_json* definitions may involve lots of database point queries and method calls. When returning collections of objects, a single call may yield hundreds of database queries that can take seconds. This library mitigates the problem by implementing a module called *CachedJson*.

CachedJson enables returning multiple JSON formats and versions from a single class and provides some rules for returning embedded or referenced data. It then uses a scheme where fragments of JSON are cached for a particular (class, id) pair containing only the data that doesn't involve references/embedded documents. To get the full JSON for an instance, CachedJson will combine fragments of JSON from the instance with fragments representing the JSON for its references. In the best case, when all of these fragments are cached, this falls through to a few cache lookups followed by a couple Ruby hash merges to create the JSON.

Using Mongoid::CachedJson we were able to cut our JSON API average response time by about a factor of 10.

Resources
---------

* [Need Help?](http://groups.google.com/group/mongoid-cached-json)
* [Source Code](http://github.com/dblock/mongoid-cached-json)
* [Travis CI](https://secure.travis-ci.org/dblock/mongoid-cached-json)

Quickstart
----------

Add `mongoid-cached-json` to your Gemfile.

    gem "mongoid-cached-json"

Include `Mongoid::CachedJson` in your models.

``` ruby
class Gadget
  include Mongoid::CachedJson

  field :name
  field :extras

  belongs_to :widget

  json_fields \
    :name => { },
    :extras => { :properties => :public }

end

class Widget
  include Mongoid::CachedJson

  field :name
  has_many :gadgets

  json_fields \
    :name => { },
    :gadgets => { :type => :reference, :properties => :public }

end
```

Invoke `as_json`.

``` ruby
# the `:short` version of the JSON, `gadgets` not included
Widget.first.as_json

# equivalent to the above
Widget.first.as_json({ :properties => :short })

# `:public` version of the JSON, `gadgets` returned with `:short` JSON, no `:extras`
Widget.first.as_json({ :properties => :public })

# `:all` version of the JSON, `gadgets` returned with `:all` JSON, including `:extras`
Widget.first.as_json({ :properties => :all })
```

Configuration
-------------

By default `Mongoid::CachedJson` will use an instance of `ActiveSupport::Cache::MemoryStore` in a non-Rails and `Rails.cache` in a Rails environment. You can configure it to use any other cache store.

``` ruby
Mongoid::CachedJson.configure do |config|
  config.cache = ActiveSupport::Cache::FileStore.new
end
```

The default JSON version returned from `as_json` is `:unspecified`. If you wish to redefine this, set `Mongoid::CachedJson.config.default_version`.

``` ruby
Mongoid::CachedJson.configure do |config|
  config.default_version = :v2
end
```

Defining Fields
---------------

Mongoid::CachedJson supports the following options.

{'fraction_non_alphanumeric': 0.1213490398579958, 'fraction_numerical': 0.0009682104243989027, 'mean_word_length': 4.28839590443686, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '692305', 'n_tokens_mistral': 1828, 'n_tokens_neox': 1781, 'n_words': 676}