Skip to content

Combine query links using OR #640

@joseph-neeraj

Description

@joseph-neeraj

Is there an existing issue?

No.

Build info

  • objectbox version: 4.0.0
  • Flutter/Dart version: Flutter 3.22.1, Dart 3.4.1
  • Build OS: Ubuntu 22.04.4
    Deployment OS: Android 11

Steps to reproduce

I have these 2 entities:

@Entity()
class Account {
  @Id()
  int id = 0;
}


@Entity()
class Transaction {

  @Id()
  int id = 0;
  
  @Property(type: PropertyType.date)
  DateTime timestamp;

  final fromAccount = ToOne<Account>();
  final toAccount = ToOne<Account>();
}

I need to query all transactions from or to a particular account. Tried this but it doesn't work:

Future<List<Transaction>> getAllTransactionsForAccount(int accountId) {
    QueryBuilder<Transaction> builder = box.query();
    builder.link(
        Transaction_.toAccount, Account_.id.equals(accountId));
    builder.link(
        Transaction_.fromAccount, Account_.id.equals(accountId));
    Query<Transaction> q = builder.build();
    return q.findAsync();
  }

Expected behavior

The query should return all transactions that have the specified fromAccount id OR toAccount id.
The query builder doesn't allow you to specify if the relation is an OR or AND, so it would be nice if we could specify that too.

Actual behavior

The list returned is empty.
This is the workaround that does work, but the list can be quite large and sorting in the main thread isn't ideal:

Future<List<Transaction>> getAllTransactionsForPocket(int pocketId) async {
    final QueryBuilder<Transaction> q1Builder = box.query();
    q1Builder.link(
        Transaction_.toPocketRelationForObjectbox, Pocket_.id.equals(pocketId));
    final Query<Transaction> q1 = q1Builder.build();
    final List<Transaction> q1Results = await q1.findAsync();

    final QueryBuilder<Transaction> q2Builder = box.query();
    q2Builder.link(Transaction_.fromPocketRelationForObjectBox,
        Pocket_.id.equals(pocketId));
    final Query<Transaction> q2 = q2Builder.build();
    final List<Transaction> q2Results = await q2.findAsync();

    final List<Transaction> combined = [...q1Results, ...q2Results];
    combined.sort((t1, t2) => t2.timestamp.compareTo(t1.timestamp));

    return combined;
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already existsenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions