Moebius v2.0.0 Moebius.DocumentQuery

If you like your Postgres doing document goodness, then you’ll want to use this interface. Just include it in your module and you can work directly with JSONB in PostgreSQL. We’ve tried to keep reasonable parity with the Query interface, but there are some concepts here that are a bit different.

This entire module is predicated on a very particular structure for your document table. You don’t need to create this table yourself, we’ll do it for you on save/2 if it does not exist.

If you want to create it yourself, the SQL is:

create table NAME(
  id serial primary key not null,
  body jsonb not null,
  search tsvector,
  created_at timestamptz not null default now(),
  updated_at timestamptz
);

-- index the search and jsonb fields
create index idx_NAME_search on NAME using GIN(search);
create index idx_NAME on NAME using GIN(body jsonb_path_ops);

Using this structure we can apply some convention, making this interface particularly compelling. Of primary note is the Full Text search, this ability (and speed) is what sets PostgreSQL above other document systems.

Summary

Functions

This is analagous to filter with the Query module, however this method is highly optimized for JSONB as it uses the @ (contains) operator. This flexes the GIN index created for your table (see above)

Specifies the table or view you want to query and is an alias for the db/1 function using a string as a table name. This is useful for specifying a table within a schema

Deletes a document based on the filter (if any)

Deletes a document with the given id

Deletes a document with the given id

Queries a table using the existence operator. Not a good query to run on a large table as it needs to do a full scan in order to match, and can’t use the built-in index, however if you need to query embedded arrays this is a good choice. If possible, use contains/2

Queries a table using matching string criteria. Not a good query to run on a large table as it needs to do a full scan in order to match, and can’t use the built-in index, however if you need to do a specialized query this is a good choice. If possible, use contains/2

Queries a table using matching criteria. Not a good query to run on a large table as it needs to do a full scan in order to match, and can’t use the built-in index, however if you need to do a specialized query this is a good choice. If possible, use contains/2

Finds a document based on ID using the Primary Key index. An optimized query for finding a single document

Alias for Query limit

Alias for Query offset

An alias for delete/1, removes a document based on the filter setup

An alias for delete/2, removes a document with the specified ID

An alias for delete/2, removes a document with the specified ID

Performs a Full Text query using a full table scan. Not a good choice for larger tables. If possible, specify your search columns on save/3 and use search/2

Marks a set of fields for indexing during save

Creates a SELECT command based on the assembled pipeline

Sorts the query based on the supplied criteria

Functions

contains(cmd, criteria)

This is analagous to filter with the Query module, however this method is highly optimized for JSONB as it uses the @ (contains) operator. This flexes the GIN index created for your table (see above).

criteria: - A list of elements to look for. This list must be complete, partial matches won’t work.

Example:

db(:user_docs)
  |> contains(email: "test@test.com")
  |> first
db(table)

Specifies the table or view you want to query and is an alias for the db/1 function using a string as a table name. This is useful for specifying a table within a schema.

“table” - the name of the table you want to query, such as membership.user_docs

Example

result = with("membership.user_docs")
  |> to_list
decide_command(cmd, doc)
delete(cmd)

Deletes a document based on the filter (if any)

delete(cmd, pid)

Deletes a document with the given id

delete(cmd, pid, id)

Deletes a document with the given id

exists(cmd, field, params)

Queries a table using the existence operator. Not a good query to run on a large table as it needs to do a full scan in order to match, and can’t use the built-in index, however if you need to query embedded arrays this is a good choice. If possible, use contains/2

Example:

return = db(:user_docs)
  |> exists(:pets, "skippy") # :pets is an array
  |> to_list
filter(cmd, criteria, params \\ [])

Queries a table using matching string criteria. Not a good query to run on a large table as it needs to do a full scan in order to match, and can’t use the built-in index, however if you need to do a specialized query this is a good choice. If possible, use contains/2

Example:

return = db(:user_docs)
  |> filter("body -> 'email' = $1", res.email)
  |> first
filter(cmd, field, operator, params)

Queries a table using matching criteria. Not a good query to run on a large table as it needs to do a full scan in order to match, and can’t use the built-in index, however if you need to do a specialized query this is a good choice. If possible, use contains/2

Example:

return = db(:user_docs)
  |> filter(:id, ">", 100)
  |> to_list
find(cmd, id)

Finds a document based on ID using the Primary Key index. An optimized query for finding a single document.

Example:

return = db(:user_docs)
  |> find(12)
insert(cmd, doc)
limit(cmd, len)

Alias for Query limit

offset(cmd, len)

Alias for Query offset

remove(cmd)

An alias for delete/1, removes a document based on the filter setup.

remove(cmd, pid)

An alias for delete/2, removes a document with the specified ID.

remove(cmd, pid, id)

An alias for delete/2, removes a document with the specified ID.

search(cmd, term)

Performs a Full Text query using a full table scan. Not a good choice for larger tables. If possible, specify your search columns on save/3 and use search/2.

Example:

users = db(:user_docs)
  |> search(for: "test.com", in: [:email])
searchable(arg)

Marks a set of fields for indexing during save.

Example:

product = %{sku: "TEST_1", name: "Test Product", description: "Just a test"}
return = db(:products)
  |> searchable([:name, :description])
  |> save(product)
searchable(cmd, search_params)
select(cmd)

Creates a SELECT command based on the assembled pipeline.

sort(cmd, cols, direction \\ :asc)

Sorts the query based on the supplied criteria.

Example:

return = db(:user_docs)
  |> exists(:pets, "skippy") # :pets is an array
  |> sort(:city)
  |> to_list
update(cmd, change, id)