<commit_before>var methods = {
  /**
   * Set up a search index.
   *
   * @param name
   * @param options
   * @returns {void}
   */
  'createSearchIndex' : function (name, options) {
    if (Meteor.isServer && options.useTextIndexes) {
      var indexDoc = EasySearch._transformFieldsToIndexDocument(options.field),
        rawCollection = EasySearch.getIndex(name).collection.rawCollection(),
        indexOptions = { name: name };

      if (options.weights) {
        indexOptions.weights = options.weights();
      }

      rawCollection.createIndex(
        indexDoc, indexOptions, function (err, res) {
          options.onCreatedIndex && options.onCreatedIndex(res);
        }
      );
    }
  },
  /**
   *
   * Perform a really simple search with mongo db.
   *
   * @param {String} name
   * @param {String} searchString
   * @param {Object} options
   * @param {Function} callback
   * @returns {Object}
   */
  'search' : function (name, searchString, options, callback) {
    var cursor,
      results,
      selector,
      cursorOptions,
      pipeline,
      aggregates,
      index = EasySearch.getIndex(name);

    if (!_.isObject(index)) {
      return;
    }

    options.limit = options.limit || 10;

    // if several, fields do an $or search, otherwise only over the field
    selector = index.query(searchString, options);

    if (!selector) {
      return { total: 0, results: [] };
    }

    cursorOptions = {
      sort : index.sort(searchString, options)
    };

    if (options.returnFields) {
      cursorOptions.fields = EasySearch._transformToFieldSpecifiers(options.returnFields);
    }

    if (options.skip) {
      cursorOptions.skip = options.skip;
    }

    cursorOptions.limit = options.limit;

    cursor = index.collection.find(selector, cursorOptions);

    // Get the total count by aggregating
    pipeline = [
      {$match: selector},
      {$group: {
        _id: "id",
        total: {$sum: 1}
      }}
    ];
    aggregates = index.collection.aggregate(pipeline);

    results = {
      'results' : cursor.fetch(),
      'total' : aggregates.length >= 1 ? aggregates[0].total : 0
    };

    if (_.isFunction(callback)) {
      callback(results);
    }

    return results;
  },
  /**
   * The default mongo-db query - selector used for searching.
   *
   * @param {Object} conf
   * @param {String} searchString
   * @param {Function} regexCallback
   *
   * @returns {Object}
   */
  'defaultQuery' : function (conf, searchString, regexCallback) {
    if (Meteor.isServer && conf.useTextIndexes) {
      return { $text: { $search: searchString } };
    } else if (Meteor.isClient || !conf.useTextIndexes) {
      // Convert numbers if configured
      if (conf.convertNumbers && parseInt(searchString, 10) == searchString) {
        searchString = parseInt(searchString, 10);
      }

      var stringSelector = { '$regex' : '.*' + searchString + '.*', '$options' : 'i'},
        selector = {
          $or: []
        };

      if (regexCallback) {
        stringSelector['$regex'] = regexCallback(searchString);
      }

      _.each(conf.field, function (fieldString) {
        var orSelector = {};

        if (_.isString(searchString)) {
          orSelector[fieldString] = stringSelector;
        } else if (_.isNumber(searchString)) {
          orSelector[fieldString] = searchString;
        }

        selector['$or'].push(orSelector);
      });

      return selector;
    }
  },
  /**
   * The default mongo-db sorting method used for sorting the results.
   *
   * @param {Object} conf
   * @return array
   */
  'defaultSort' : function (conf) {
    return conf.field;
  }
};

if (Meteor.isClient) {
  EasySearch.createSearcher('minimongo', methods);
} else if (Meteor.isServer) {
  EasySearch.createSearcher('mongo-db', methods);
}

<commit_msg>Added fallback to the old way of counting search results when running on client.<commit_after>var methods = {
  /**
   * Set up a search index.
   *
   * @param name
   * @param options
   * @returns {void}
   */
  'createSearchIndex' : function (name, options) {
    if (Meteor.isServer && options.useTextIndexes) {
      var indexDoc = EasySearch._transformFieldsToIndexDocument(options.field),
        rawCollection = EasySearch.getIndex(name).collection.rawCollection(),
        indexOptions = { name: name };

      if (options.weights) {
        indexOptions.weights = options.weights();
      }

      rawCollection.createIndex(
        indexDoc, indexOptions, function (err, res) {
          options.onCreatedIndex && options.onCreatedIndex(res);
        }
      );
    }
  },
  /**
   *
   * Perform a really simple search with mongo db.
   *
   * @param {String} name
   * @param {String} searchString
   * @param {Object} options
   * @param {Function} callback
   * @returns {Object}
   */
  'search' : function (name, searchString, options, callback) {
    var cursor,
      results,
      selector,
      cursorOptions,
      index = EasySearch.getIndex(name);

    if (!_.isObject(index)) {
      return;
    }

    options.limit = options.limit || 10;

    // if several, fields do an $or search, otherwise only over the field
    selector = index.query(searchString, options);

    if (!selector) {
      return { total: 0, results: [] };
    }

    cursorOptions = {
      sort : index.sort(searchString, options)
    };

    if (options.returnFields) {
      cursorOptions.fields = EasySearch._transformToFieldSpecifiers(options.returnFields);
    }

    if (options.skip) {
      cursorOptions.skip = options.skip;
    }

    if (Meteor.isServer) {
      // When running on server, we can improve the performance by computing the total count by using aggregation
      cursorOptions.limit = options.limit;
      cursor = index.collection.find(selector, cursorOptions);

      // Get the total count by aggregating
      var pipeline = [
        {$match: selector},
        {
          $group: {
            _id: "id",
            total: {$sum: 1}
          }
        }
      ];
      var aggregates = index.collection.aggregate(pipeline);

      results = {
        'results': cursor.fetch(),
        'total': aggregates.length >= 1 ? aggregates[0].total : 0
      };
    } else {
      // The aggregate operations are not supported on client,
      // so we have to explicitly count all records in the search result
      cursor = index.collection.find(selector, cursorOptions);

      results = {
        'results' : _.first(cursor.fetch(), options.limit),
        'total' : cursor.count()
      };
    }

    if (_.isFunction(callback)) {
      callback(results);
    }

    return results;
  },
  /**
   * The default mongo-db query - selector used for searching.
   *
   * @param {Object} conf
   * @param {String} searchString
   * @param {Function} regexCallback
   *
   * @returns {Object}
   */
  'defaultQuery' : function (conf, searchString, regexCallback) {
    if (Meteor.isServer && conf.useTextIndexes) {
      return { $text: { $search: searchString } };
    } else if (Meteor.isClient || !conf.useTextIndexes) {
      // Convert numbers if configured
      if (conf.convertNumbers && parseInt(searchString, 10) == searchString) {
        searchString = parseInt(searchString, 10);
      }

      var stringSelector = { '$regex' : '.*' + searchString + '.*', '$options' : 'i'},
        selector = {
          $or: []
        };

      if (regexCallback) {
        stringSelector['$regex'] = regexCallback(searchString);
      }

      _.each(conf.field, function (fieldString) {
        var orSelector = {};

        if (_.isString(searchString)) {
          orSelector[fieldString] = stringSelector;
        } else if (_.isNumber(searchString)) {
          orSelector[fieldString] = searchString;
        }

        selector['$or'].push(orSelector);
      });

      return selector;
    }
  },
  /**
   * The default mongo-db sorting method used for sorting the results.
   *
   * @param {Object} conf
   * @return array
   */
  'defaultSort' : function (conf) {
    return conf.field;
  }
};

if (Meteor.isClient) {
  EasySearch.createSearcher('minimongo', methods);
} else if (Meteor.isServer) {
  EasySearch.createSearcher('mongo-db', methods);
}


{'fraction_non_alphanumeric': 0.12908337396392003, 'fraction_numerical': 0.002681618722574354, 'mean_word_length': 2.427318295739348, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, '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': '4474744', 'n_tokens_mistral': 2459, 'n_tokens_neox': 2389, 'n_words': 574}