function matchQuery(record, query = {}) {

  if (query.$not) {
    return !matchQuery(record, query.$not)
  }

  if (query.$and) {
    return query.$and.every(subQuery => matchQuery(record, subQuery))
  }

  if (query.$or) {
    return query.$or.some(subQuery => matchQuery(record, subQuery))
  }

  return Object.entries(query).every(([field, condition]) => {
    const value = record[field]

    if (condition !== null && (Array.isArray(condition) || typeof condition !== 'object')) {
      return equals(value, condition)
    }

    return Object.entries(condition || {}).every(([operator, target]) => {
      switch (operator) {
      case '$gt':
        return value > target
      case '$gte':
        return value >= target
      case '$lt':
        return value < target
      case '$lte':
        return value <= target
      case '$ne':
        return !equals(value, target)
      case '$in':
        return Array.isArray(target) && target.includes(value)
      case '$nin':
        return Array.isArray(target) && !target.includes(value)
      case '$not':
        return !matchQuery({ [field]: value }, { [field]: target })
      default:
        return true
      }
    })
  })
}
Match a record against a query filter

@param {any} record
@param {ParquetQueryFilter} query
@returns {boolean}
@example matchQuery({ id: 1 }, { id: {$gte: 1} }) // true