static getHunts (req, res) {
    const query = {
      sort: {},
      from: parseInt(req.query.start) || 0,
      size: parseInt(req.query.length) || 10000,
      query: { bool: { filter: [] } }
    };

    query.sort[req.query.sortField || 'created'] = { order: req.query.desc === 'true' ? 'desc' : 'asc' };

    if (req.query.history) { // only get finished jobs
      query.query.bool.filter.push({ term: { status: 'finished' } });
      if (req.query.searchTerm) { // apply search term
        query.query.bool.filter.push({
          query_string: {
            query: req.query.searchTerm,
            fields: ['name', 'userId']
          }
        });
      }
    } else { // get queued, paused, running jobs
      query.from = 0;
      query.size = 1000;
      if (req.query.all === undefined) {
        query.query.bool.filter.push({ terms: { status: ['queued', 'paused', 'running'] } });
      }
    }

    if (Config.debug) {
      console.log('Hunt query:', JSON.stringify(query, null, 2));
    }

    Promise.all([
      Db.searchHunt(query, req.query.cluster),
      Db.countHunts(req.query.cluster),
      Db.getQueriesNode()
    ]).then(([{ body: { hits: hunts } }, { body: { count: total } }, nodeInfo]) => {
      let runningJob;

      const results = { total: hunts.total, results: [] };
      for (let i = 0, ilen = hunts.hits.length; i < ilen; i++) {
        const hit = hunts.hits[i];
        const hunt = hit._source;
        hunt.id = hit._id;
        hunt.index = hit._index;
        hunt.users = hunt.users || [];

        // clear out secret fields for users who don't have access to that hunt
        // if the user is not an admin and didn't create the hunt and isn't part of the user's list
        if (!req.user.hasRole('arkimeAdmin') && req.user.userId !== hunt.userId && hunt.users.indexOf(req.user.userId) < 0) {
          if (!hunt.roles || (hunt.roles.length && !req.user.hasRole(hunt.roles))) {
            // since hunt isn't cached we can just modify
            hunt.id = '';
            hunt.search = '';
            hunt.userId = '';
            hunt.searchType = '';
            delete hunt.query;
          }
        }

        // don't add the running job to the queue
        if (hunt.status === 'running' && (!CronAPIs.isPrimaryViewer() || internals.runningHuntJob)) {
          runningJob = hunt;
          if (req.query.all !== undefined) {
            continue;
          }
        }
        results.results.push(hunt);
      }

      res.send({
        recordsTotal: total,
        recordsFiltered: results.total,
        data: results.results,
        runningJob,
        nodeInfo
      });
    }).catch(err => {
      console.log(`ERROR - ${req.method} /api/hunts`, util.inspect(err, false, 50));
      return res.serverError(500, 'Error retrieving hunts');
    });
  }
GET - /api/hunts

Retrieves a list of hunts.
@name /hunts
@param {string} searchTerm - The search text to search hunt results for.
@param {number} length=10000 - The number of items to return. Defaults to 10000.
@param {number} start=0 - The entry to start at. Defaults to 0
@param {string} sortField=created - The field to sort the hunt results by. Defaults to "created".
@param {string} desc=false - Whether to sort the results in descending order. Default is ascending.
@param {string} history=false - Whether to return only finished hunts. Default is to return queued, paused, and running hunts.
@returns {Hunt} runningJob - If there is a hunt running, returns the currently running hunt object.
@returns {Hunt[]} data - The list of hunts (either finished or queued/paused/running).
@returns {number} recordsTotal - The total number of hunts Arkime has.
@returns {number} recordsFiltered - The number of hunts returned in this result.