I know the claim was to avoid "revisions" and "conflicts" discussion in
this thread but isn't that unavoidable.

In scheme #1 you have multiple keys with the same DOCID/PART_IDX but
different data.
In schemes #2 / #3 you have multiple copies of the JSON_PATH but different
values.

The trivial fix is to use DOCID/REVISIONID as DOC_KEY.

Mike

On Wed, Jan 30, 2019 at 9:53 AM Ilya Khlopotov <iil...@apache.org> wrote:

> FoundationDB Records layer uses global schema for JSON documents. They
> also have a nice way of creating indexes and schema evolution support.
> However this support comes at a cost of extra lookups in different
> subspace. With local mapping table we almost (except a corner case) certain
> that the schema and JSON fields would be collocated on a single node. Due
> to common prefix.
>
> Best regards,
> iilyak
> On 2019/01/30 17:05:01, Jan Lehnardt <j...@apache.org> wrote:
> > Ah sure, if we store the *cough* schema per doc, then it's not that
> easy. An iteration of this proposal could store paths globally with ids
> that the k/v store then uses for keys, which would enable what I described,
> but happy to ignore this for the time being. :)
> >
> > Cheers
> > Jan
> > —
> >
> > > On 30. Jan 2019, at 17:58, Adam Kocoloski <kocol...@apache.org> wrote:
> > >
> > > Jan, I don’t think it does have that "fun property #2", as the mapping
> is created separately for each document. In this proposal the field name
> “foo” could map to 2 in one document and 42 in another.
> > >
> > > Thanks for the proposal Ilya. Personally I wonder if the 10KB limit on
> field paths is anything more than a theoretical concern. It’s hard for me
> to imagine a useful schema that would get anywhere near that deep, but
> maybe I’m insufficiently creative :) There’s certainly a storage overhead
> from repeating the upper portion of a path over and over again, but that’s
> also something the storage engine can optimize away through prefix elision.
> The current production storage engine in FoundationDB does not do this
> elision, but the new one in development does.
> > >
> > > The value size limit is probably not so theoretical. I think as a
> project we could choose to impose a 100KB size limit on scalar values - a
> user who had a string longer than 100KB could chunk it up into an array of
> strings pretty easily to work around that limit. But let’s say we don’t
> want to impose that limit. In your design, how do I distinguish {PART_IDX}
> from the elements of the {JSON_PATH}? I was kind of expecting to see some
> magic value indicating that the subsequent set of keys with the same prefix
> are all elements of a “multi-part object”:
> > >
> > > {DB_DOCS_NS} / {DOC_KEY} / {JSON_PATH}  = kMULTIPART
> > > {DB_DOCS_NS} / {DOC_KEY} / {JSON_PATH} / {PART_IDX}  = “First 100 KB …"
> > > ...
> > >
> > > You might have figured out something more efficient that saves a KV
> here but I can’t quite grok it.
> > >
> > > Cheers, Adam
> > >
> > >
> > >> On Jan 30, 2019, at 8:24 AM, Jan Lehnardt <j...@apache.org> wrote:
> > >>
> > >>
> > >>
> > >>> On 30. Jan 2019, at 14:22, Jan Lehnardt <j...@apache.org <mailto:
> j...@apache.org>> wrote:
> > >>>
> > >>> Thanks Ilya for getting this started!
> > >>>
> > >>> Two quick notes on this one:
> > >>>
> > >>> 1. note that JSON does not guarantee object key order and that
> CouchDB has never guaranteed it either, and with say emit(doc.foo,
> doc.bar), if either emit() parameter was an object, the
> undefined-sort-order of SpiderMonkey would mix things up. While worth
> bringing up, this is not a BC break.
> > >>>
> > >>> 2. This would have the fun property of being able to rename a key
> inside all docs that have that key.
> > >>
> > >> …in one short operation.
> > >>
> > >> Best
> > >> Jan
> > >> —
> > >>>
> > >>> Best
> > >>> Jan
> > >>> —
> > >>>
> > >>>> On 30. Jan 2019, at 14:05, Ilya Khlopotov <iil...@apache.org>
> wrote:
> > >>>>
> > >>>> # First proposal
> > >>>>
> > >>>> In order to overcome FoudationDB limitations on key size (10 kB)
> and value size (100 kB) we could use the following approach.
> > >>>>
> > >>>> Bellow the paths are using slash for illustration purposes only. We
> can use nested subspaces, tuples, directories or something else.
> > >>>>
> > >>>> - Store documents in a subspace or directory  (to keep prefix for a
> key short)
> > >>>> - When we store the document we would enumerate all field names (0
> and 1 are reserved) and store the mapping table in the key which look like:
> > >>>> ```
> > >>>> {DB_DOCS_NS} / {DOC_KEY} / 0
> > >>>> ```
> > >>>> - Flatten the JSON document (convert it into key value pairs where
> the key is `JSON_PATH` and value is `SCALAR_VALUE`)
> > >>>> - Replace elements of JSON_PATH with integers from mapping table we
> constructed earlier
> > >>>> - When we have array use `1 / {array_idx}`
> > >>>> - Store scalar values in the keys which look like the following (we
> use `JSON_PATH` with integers).
> > >>>> ```
> > >>>> {DB_DOCS_NS} / {DOC_KEY} / {JSON_PATH}
> > >>>> ```
> > >>>> - If the scalar value exceeds 100kB we would split it and store
> every part under key constructed as:
> > >>>> ```
> > >>>> {DB_DOCS_NS} / {DOC_KEY} / {JSON_PATH} / {PART_IDX}
> > >>>> ```
> > >>>>
> > >>>> Since all parts of the documents are stored under a common
> `{DB_DOCS_NS} / {DOC_KEY}` they will be stored on the same server most of
> the time. The document can be retrieved by using range query
> (`txn.get_range("{DB_DOCS_NS} / {DOC_KEY} / 0", "{DB_DOCS_NS} / {DOC_KEY} /
> 0xFF")`). We can reconstruct the document since the mapping is returned as
> well.
> > >>>>
> > >>>> The downside of this approach is we wouldn't be able to ensure the
> same order of keys in the JSON object. Currently the `jiffy` JSON encoder
> respects order of keys.
> > >>>> ```
> > >>>> 4> jiffy:encode({[{bbb, 1}, {aaa, 12}]}).
> > >>>> <<"{\"bbb\":1,\"aaa\":12}">>
> > >>>> 5> jiffy:encode({[{aaa, 12}, {bbb, 1}]}).
> > >>>> <<"{\"aaa\":12,\"bbb\":1}">>
> > >>>> ```
> > >>>>
> > >>>> Best regards,
> > >>>> iilyak
> > >>>>
> > >>>>> On 2019/01/30 13:02:57, Ilya Khlopotov <iil...@apache.org> wrote:
> > >>>>> As you might already know the FoundationDB has a number of
> limitations which influences the way we might store JSON documents. The
> limitations are:
> > >>>>>
> > >>>>> |      limitation             |recommended value|recommended
> max|absolute max|
> > >>>>>
> |-------------------------|----------------------:|--------------------:|--------------:|
> > >>>>> | transaction duration  |                              |
>                  |      5 sec      |
> > >>>>> | transaction data size |                              |
>                  |      10 Mb     |
> > >>>>> | key size                   |                 32 bytes |
>          1 kB  |     10 kB      |
> > >>>>> | value size                |                               |
>             10 kB |    100 kB     |
> > >>>>>
> > >>>>> In order to fit the JSON document into 100kB we would have to
> partition it in some way. There are three ways of partitioning the document
> > >>>>> 1. store multiple binary blobs (parts) in different keys
> > >>>>> 2. flatten JSON structure and store every path leading to a scalar
> value under own key
> > >>>>> 3. measure the size of different branches of a tree representing
> the JSON document (while we parse) and use another key for the branch when
> we about to exceed the limit
> > >>>>>
> > >>>>> - The first approach is the simplest but it wouldn't allow us to
> access parts of the document.
> > >>>>> - The downsides of a second approach are:
> > >>>>> - flattened JSON structure would have long paths which means
> longer keys
> > >>>>> - the scalar value cannot be more than 100kb (unless we split it
> as well)
> > >>>>> - Third approach falls short in cases when the structure of the
> document doesn't allow a clean cut off branches:
> > >>>>> - complex rules to handle all corner cases
> > >>>>>
> > >>>>> The goals of this thread are:
> > >>>>> - to collect ideas on how to encode and store the JSON document
> > >>>>> - to comment on the collected ideas
> > >>>>>
> > >>>>> Non goals:
> > >>>>> - the storage of metadata for the document would be discussed
> elsewhere
> > >>>>> - thumb stones
> > >>>>> - edit conflicts
> > >>>>> - revisions
> > >>>>>
> > >>>>> Best regards,
> > >>>>> iilyak
> > >>>>>
> > >>>
> > >>> --
> > >>> Professional Support for Apache CouchDB:
> > >>> https://neighbourhood.ie/couchdb-support/
> > >>>
> > >>
> > >> --
> > >> Professional Support for Apache CouchDB:
> > >> https://neighbourhood.ie/couchdb-support/ <
> https://neighbourhood.ie/couchdb-support/>
> >
> >
>

Reply via email to