Mutating the shape of data stored in the db vs. what's presented in Ecto struct (without embedded schema)

This is more of a educational question… usually, my Ecto schemas match the column names in my database pretty closely. Every now and then I specify the :source option in my field definitions if I want my Ecto schema to use a different field name than what’s in the database.

But how flexible is Ecto when you want your Ecto struct to be very different from what’s in the database. For example, let’s say we want a struct like this:

@type t :: %__MODULE__{
  a: String.t()
  b: integer()
  c: boolean()
}

but our database is actually defined like this:

defmodule Foo do
    use Ecto.Schema
    
    @primary_key false
    schema "bar" do
      field(:a, :string, null: false)
      field(:meta, :map)
    end  
  end

The idea being that the b and c values are persisted inside the meta map. Is this possible in Ecto? (And I realize that deviating too much between the 2 representations here can be confusing/unhelpful). But I’m curious – can it be done and how? Thanks in advance!