Esempio n. 1
0
def _build_intersecting_query(
    filter_group: sql.FilterGroup,
    acc_query: typing.Optional[QueryExpression],
    table: sql.Table,
    direction: str,
) -> QueryExpression:
    opposite_direction = "left" if direction == "right" else "right"
    document_set = build_document_set_intersection(table, filter_group)

    if acc_query is None:
        intersection = document_set
    else:
        intersection = q.intersection(acc_query, document_set)

    next_table = getattr(table, f"{direction}_join_table")

    if next_table is None or table.has_columns:
        return intersection

    next_join_key = getattr(table, f"{direction}_join_key")
    assert next_join_key is not None

    if next_join_key.name == "ref":
        next_foreign_key = getattr(next_table,
                                   f"{opposite_direction}_join_key")
        assert next_foreign_key is not None

        return _build_intersecting_query(
            filter_group,
            q.join(
                intersection,
                q.index(
                    index_name(
                        next_table.name,
                        column_name=next_foreign_key.name,
                        index_type=IndexType.REF,
                    )),
            ),
            next_table,
            direction,
        )

    return _build_intersecting_query(
        filter_group,
        q.join(
            intersection,
            q.index(
                index_name(
                    table.name,
                    index_type=IndexType.REF,
                    foreign_key_name=next_join_key.name,
                )),
        ),
        next_table,
        direction,
    )
Esempio n. 2
0
def _sort_document_set(document_set: QueryExpression,
                       order_by: typing.Optional[sql.OrderBy]):
    if order_by is None:
        return q.paginate(document_set, size=common.MAX_PAGE_SIZE)

    if len(order_by.columns) > 1:
        raise exceptions.NotSupportedError(
            "Ordering by multiple columns is not yet supported.")

    ordered_column = order_by.columns[0]
    assert ordered_column.table_name is not None

    ordered_document_set = q.join(
        document_set,
        q.index(
            common.index_name(
                ordered_column.table_name,
                column_name=ordered_column.name,
                index_type=common.IndexType.SORT,
            )),
    )
    if order_by.direction == sql.OrderDirection.DESC:
        ordered_document_set = q.reverse(ordered_document_set)

    return q.map_(
        q.lambda_(["_", "ref"], q.var("ref")),
        q.paginate(ordered_document_set, size=common.MAX_PAGE_SIZE),
    )
Esempio n. 3
0
    def test_join(self):
        join_refs = [self._create(n=12)["ref"], self._create(n=12)["ref"]]
        assoc_refs = [self._create(m=ref)["ref"] for ref in join_refs]

        source = query.match(self.n_index_ref, 12)
        self.assertEqual(self._set_to_list(source), join_refs)

        # For each obj with n=12, get the set of elements whose data.m refers to it.
        joined = query.join(source, lambda a: query.match(self.m_index_ref, a))
        self.assertEqual(self._set_to_list(joined), assoc_refs)
Esempio n. 4
0
def convert_to_ref_set(collection_name: str,
                       index_match: QueryExpression) -> QueryExpression:
    """Convert value-based match set to set of refs.

    Params:
    -------
    collection_name: Name of the source collection for the index.
    index_match: Match set of the index. Index must have values attribute of the form
        [{"field": ["data", <field>]}, {"field": ["ref"}]}]
    """
    return q.join(
        index_match,
        q.lambda_(
            ["value", "ref"],
            q.match(
                q.index(index_name(collection_name, index_type=IndexType.REF)),
                q.var("ref"),
            ),
        ),
    )
Esempio n. 5
0
def get_products(name=None, category=None, sort_by=None, size=5, after=None, before=None):
    sortDic = { 
        "price_asc":  q.index('products_sort_by_price_asc'),
        "price_desc": q.index('products_sort_by_price_desc'),
        "name_asc": q.index('products_sort_by_name_asc'),
        'created_at_asc': q.index('products_sort_by_created_asc')
    }

    matches = []
    if(name):
        matches.append(q.match(q.index('products_search_by_name'), name))

    if(category):
        matches.append(q.match(
            q.index('products_search_by_category'),
            q.ref(q.collection('categories'), category)
        ))

    if(len(matches) == 0):
        matches.append(q.documents(q.collection('products')))

    return fauna.query(
        q.map_(
            lambda _, ref: q.get(ref),
            q.paginate(
                q.join(
                    q.intersection(matches),
                    sortDic[sort_by or 'name_asc']
                ),
                size=size,
                after=after,
                before=before
            )
            
        )
    )
 def test_join(self):
     self.assertJson(
         query.join(query.match(query.index("widget")),
                    query.index("things")),
         '{"join":{"match":{"index":"widget"}},"with":{"index":"things"}}')