<commit_before># maximum:computed-fields [![Build Status](https://travis-ci.org/maximummeteor/computed-fields.svg)](https://travis-ci.org/maximummeteor/computed-fields)
Meteor package for automatic computation of field values in a collection

## What it does

Let's think you have two collections, authors and posts. Posts have one author.
You want to display the number of posts an author has written on the author's page. Normally in Meteor you would publish the posts for an author and do a `Posts.find({authorId: '...'}).count()`. But if an author has written a large number of posts, it can be slow.
At this point, it's better to use computed fields instead of doing the computation on-the-fly.
What if you have a field called `postCount` in the authors collection that holds the number of posts of an author and updates itself automatically?
With this package, you can achieve this with one line of code:

````javascript
  var Posts = new Mongo.Collection('posts');
  var Authors = new Mongo.Collection('authors');

  // on server side
  Authors.computedFields.add('postCount').count(Posts, 'authorId');
````

## Installation
```
    meteor add maximum:computed-fields
```

## Usage

You can add an computed field with `*collection*.computedFields.add(name, [calculation])` (on serverside only).
The first parameter `name` specify how the field should be named. It's possible to specify sub-objects with `.` (e.g. `subobject.commentsCount`)
The second parameter is optional and specifies a function with the basic computation. It will be executed on `insert`, `update` and `remove` of documents in the specified collection. It gets the affected document as the first parameter.
````javascript
  Posts.computedFields.add('commentsCount') // returns a ComputedField instance

  Posts.computedFields.add('updateCount', function(post){
    /*  
      content of `this`:
      * isUpdate (boolean)
      * isInsert (boolean)
      * isRemove (boolean)
      * previous (object)
      * userId: (string)
      * fieldNames ([string])
      * set (function)
    */
    this.set(newValue); // use `set` to update the field
  });
````

### ComputedField
|Method|Description|
|------|-----------|
|addDependency(`collection`, `options`)|Does a computation depending on a other collection. This method takes the other collection as the first parameter and an options-object as the second one:<ul><li>`findId(relatedDoc)`: Function to get the relation between the two collections. Must return an `_id` of the collection, in which the computed field is.</li><li>`update(currentDoc, relatedDoc)`: Function to update the computed field. See above for the value of `this`</li></ul> |
|simple(`collection`, `referenceFieldName`, `update`)|Does a computation depending on a other collection (a simpler approach). It takes the following parameters:<ul><li>`collection`: the other collection</li><li>`referenceFieldName`: the name of the field which contains the `_id` of the document (e.g. `authorId`).</li><li>`update(currentDoc, relatedDoc)`: function to update the computed field. Must return the new value for the computed field. See above for the value of `this`. For this function, `this` will be extended with the `increment` property. `this.increment` contains `1` if an related document was added and `-1` if a related document was removed.</li></ul>|
|increment(`collection`, `referenceFieldName`, `update`)|Same like `simple`, but the return value of the `update` function will be added to the current value instead of overwriting it. |
|count(`collection`, `referenceFieldName`)|The simplest approach. Specially for `count` properties. Works internally with `increment` and returns `this.increment`|


## Examples

### Normal computation

This is the easiest type of automatic computations. It doesn't depend on other collections.
````javascript
  //increments the field 'updateCount' every time the document gets updated (or inserted)
  Posts.computedFields.add('updateCount', function(post){
    current = post.updateCount or 0<commit_msg>describe `get` method in readme<commit_after># maximum:computed-fields [![Build Status](https://travis-ci.org/maximummeteor/computed-fields.svg)](https://travis-ci.org/maximummeteor/computed-fields)
Meteor package for automatic computation of field values in a collection

## What it does

Let's think you have two collections, authors and posts. Posts have one author.
You want to display the number of posts an author has written on the author's page. Normally in Meteor you would publish the posts for an author and do a `Posts.find({authorId: '...'}).count()`. But if an author has written a large number of posts, it can be slow.
At this point, it's better to use computed fields instead of doing the computation on-the-fly.
What if you have a field called `postCount` in the authors collection that holds the number of posts of an author and updates itself automatically?
With this package, you can achieve this with one line of code:

````javascript
  var Posts = new Mongo.Collection('posts');
  var Authors = new Mongo.Collection('authors');

  // on server side
  Authors.computedFields.add('postCount').count(Posts, 'authorId');
````

## Installation
```
    meteor add maximum:computed-fields
```

## Usage

You can add an computed field with `*collection*.computedFields.add(name, [calculation])` (on serverside only).
The first parameter `name` specify how the field should be named. It's possible to specify sub-objects with `.` (e.g. `subobject.commentsCount`)
The second parameter is optional and specifies a function with the basic computation. It will be executed on `insert`, `update` and `remove` of documents in the specified collection. It gets the affected document as the first parameter.
````javascript
  Posts.computedFields.add('commentsCount'); // returns a ComputedField instance

  Posts.computedFields.add('updateCount', function(post){
    /*  
      content of `this`:
      * isUpdate (boolean)
      * isInsert (boolean)
      * isRemove (boolean)
      * previous (object)
      * userId: (string)
      * fieldNames ([string])
      * set (function)
    */
    this.set(newValue); // use `set` to update the field
  });
````

It's also possible to get a computed field, after it was created
````javascript
  Posts.computedFields.get('commentsCount'); // returns the ComputedField instance
````

### ComputedField
|Method|Description|
|------|-----------|
|addDependency(`collection`, `options`)|Does a computation depending on a other collection. This method takes the other collection as the first parameter and an options-object as the second one:<ul><li>`findId(relatedDoc)`: Function to get the relation between the two collections. Must return an `_id` of the collection, in which the computed field is.</li><li>`update(currentDoc, relatedDoc)`: Function to update the computed field. See above for the value of `this`</li></ul> |
|simple(`collection`, `referenceFieldName`, `update`)|Does a computation depending on a other collection (a simpler approach). It takes the following parameters:<ul><li>`collection`: the other collection</li><li>`referenceFieldName`: the name of the field which contains the `_id` of the document (e.g. `authorId`).</li><li>`update(currentDoc, relatedDoc)`: function to update the computed field. Must return the new value for the computed field. See above for the value of `this`. For this function, `this` will be extended with the `increment` property. `this.increment` contains `1` if an related document was added and `-1` if a related document was removed.</li></ul>|
|increment(`collection`, `referenceFieldName`, `update`)|Same like `simple`, but the return value of the `update` function will be added to the current value instead of overwriting it. |
|count(`collection`, `referenceFieldName`)|The simplest approach. Specially for `count` properties. Works internally with `increment` and returns `this.increment`|


## Examples

### Normal computation

This is the easiest type of automatic computations. It doesn't depend on other collections.
````javascript
  //increments the field 'updateCount' every time the document gets updated (or inserted)
  Posts.computedFields.add('updateCount', function(post){
    current = post.updateCount or 0
{'fraction_non_alphanumeric': 0.10957910014513789, 'fraction_numerical': 0.000725689404934688, 'mean_word_length': 4.655950752393981, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, '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': '6010492', 'n_tokens_mistral': 2212, 'n_tokens_neox': 2104, 'n_words': 969}