function Query(conditions, options, model, collection) {
  // this stuff is for dealing with custom queries created by #toConstructor
  if (!this._mongooseOptions) {
    this._mongooseOptions = {};
  }
  options = options || {};

  this._transforms = [];
  this._hooks = new Kareem();
  this._executionStack = null;

  // this is the case where we have a CustomQuery, we need to check if we got
  // options passed in, and if we did, merge them in
  const keys = Object.keys(options);
  for (const key of keys) {
    this._mongooseOptions[key] = options[key];
  }

  if (collection) {
    this.mongooseCollection = collection;
  }

  if (model) {
    this.model = model;
    this.schema = model.schema;
  }

  // this is needed because map reduce returns a model that can be queried, but
  // all of the queries on said model should be lean
  if (this.model && this.model._mapreduce) {
    this.lean();
  }

  // inherit mquery
  mquery.call(this, null, options);
  if (collection) {
    this.collection(collection);
  }

  if (conditions) {
    this.find(conditions);
  }

  this.options = this.options || {};

  // For gh-6880. mquery still needs to support `fields` by default for old
  // versions of MongoDB
  this.$useProjection = true;

  const collation = this &&
    this.schema &&
    this.schema.options &&
    this.schema.options.collation || null;
  if (collation != null) {
    this.options.collation = collation;
  }
}
Query constructor used for building queries. You do not need
to instantiate a `Query` directly. Instead use Model functions like
[`Model.find()`](https://mongoosejs.com/docs/api/model.html#Model.find()).

#### Example:

    const query = MyModel.find(); // `query` is an instance of `Query`
    query.setOptions({ lean : true });
    query.collection(MyModel.collection);
    query.where('age').gte(21).exec(callback);

    // You can instantiate a query directly. There is no need to do
    // this unless you're an advanced user with a very good reason to.
    const query = new mongoose.Query();

@param {Object} [options]
@param {Object} [model]
@param {Object} [conditions]
@param {Object} [collection] Mongoose collection
@api public