async _mChanges(request, methodName, action) {
    let source = true;
    const userId = request.getKuid();
    const strict = request.getBoolean("strict");
    const silent = request.getBoolean("silent");
    const refresh = request.getString("refresh", "false");
    const documents = request.getBodyArray("documents");
    const { index, collection } = request.getIndexAndCollection();
    const retryOnConflict =
      action === actionEnum.UPDATE || action === actionEnum.UPSERT
        ? request.getInteger("retryOnConflict", 0)
        : undefined;

    this.assertNotExceedMaxWrite(documents.length);

    if (request.input.args.source !== undefined) {
      source =
        request.input.args.source === "false"
          ? false
          : request.getBoolean("source");
    }

    if (documents.length === 0) {
      return {
        errors: [],
        successes: [],
      };
    }

    for (let i = 0; i < documents.length; i++) {
      if (documents[i]._source) {
        throw kerror.get(
          "api",
          "assert",
          "unexpected_argument",
          `documents[${i}]._source`,
          `documents[${i}].body`,
        );
      }
    }

    const response = await this.ask(
      `core:storage:public:document:${methodName}`,
      index,
      collection,
      documents,
      { refresh, retryOnConflict, source, userId },
    );

    if (strict && response.errors.length) {
      throw kerror.get(
        "api",
        "process",
        "incomplete_multiple_request",
        methodName,
        response.errors,
      );
    }

    // @todo next major release: if (successes.length === 0) then throw (no matter strict value)

    if (
      !silent &&
      (action === actionEnum.UPDATE || action === actionEnum.UPSERT)
    ) {
      const documentsDictionnary = documents.reduce((result, document) => {
        result[document._id] =
          action === actionEnum.UPSERT ? document.changes : document.body;
        return result;
      }, {});

      await this.ask(
        "core:realtime:document:mNotify",
        request,
        action,
        response.items.map((item) => {
          if (!item.created) {
            item._updatedFields = extractFields(
              documentsDictionnary[item._id],
              { fieldsToIgnore: ["_kuzzle_info"] },
            );
          }
          return item;
        }),
      );
    } else if (!silent) {
      await this.ask(
        "core:realtime:document:mNotify",
        request,
        action,
        response.items,
      );
    }

    return {
      errors: response.errors,
      successes: response.items,
    };
  }
Applies a multi-document change request (create, update,
replace, createOrReplace, upsert)

@param  {Request} request
@param  {String} methodName ES Service method to apply
@param  {notifyActionEnum} action performed on the documents
@returns {Promise.<Object>} { successes, errors }