> But how can I do this :
>
> for k,v in pairs(obj.x) do
>    ...
> end
Like
for k, v in obj:pairs("x","y") do
        ...
end
where obj:pairs instantiates an iterator over the keys (if any) of obj.x.y.
But if the obj has multi-layers, you may write
for k,v in obj:pairs("x","y") do
     ...
     if isdocument(v) then
       for k,v in obj:pairs("x","y", k)  do
          ....
     end
end
It's hardly to use full path (like "x","y", k) every where. You may also need store them in a table. And it may be more expensive than a new proxy userdata.
I think the key abstraction here isn't Lua tables, but Lua _iterators_. I
would pursue a more declarative-programming solution, in the vein of XPath.
Only iterator is not enough.
For example, we may use a sub document as default.  Users may reference a part of the document. And then they read the records as tables, or replace values in own tables.