Skip to content

Inverted Relation Retrieval

Backendless supports a special query syntax for loading a subset of child objects for a specific parent. Consider the following table schemas:

PhoneBook table:

phonebook-table-schema

Contact table:

contact-table-schema

Address table:

address-table-schema

These tables will be used to demonstrate how to query Backendless for conditional related object retrieval.

The Map-based approach does not require you defining classes for the objects stored in Backendless. Instead your code can use java.util.Map to to store and retrieve objects in/from Backendless.
Consider the following class definitions for the entities from the diagram: PhoneBook class:
package com.sample.entity;

import java.util.List;

public class PhoneBook
{
  private String objectId;
  private Contact owner;
  private List<Contact> contacts;

  public String getObjectId()
  {
    return objectId;
  }

  public void setObjectId( String objectId )
  {
    this.objectId = objectId;
  }

  public Contact getOwner()
  {
    return owner;
  }

  public void setOwner( Contact owner )
  {
    this.owner = owner;
  }

  public List<Contact> getContacts()
  {
    return contacts;
  }

  public void setContacts( List<Contact> contacts )
  {
    this.contacts = contacts;
  }
}
Contact class:
package com.sample.entity;

import java.util.Date;

public class Contact
{
  private String objectId;
  private String name;
  private int age;
  private String phone;
  private String title;
  private Address address;
  private Date updated;

  public String getObjectId()
  {
    return objectId;
  }

  public void setObjectId( String objectId )
  {
    this.objectId = objectId;
  }

  public String getName()
  {
    return name;
  }

  public void setName( String name )
  {
    this.name = name;
  }

  public int getAge()
  {
    return age;
  }

  public void setAge( int age )
  {
    this.age = age;
  }

  public String getPhone()
  {
    return phone;
  }

  public void setPhone( String phone )
  {
    this.phone = phone;
  }

  public String getTitle()
  {
    return title;
  }

  public void setTitle( String title )
  {
    this.title = title;
  }

  public Address getAddress()
  {
    return address;
  }

  public void setAddress( Address address )
  {
    this.address = address;
  }

  public Date getUpdated()
  {
    return updated;
  }

  public void setUpdated( Date updated )
  {
    this.updated = updated;
  }
}
Address class:
package com.sample.entity;

public class Address
{
  private String street;
  private String city;
  private String state;

  public String getStreet()
  {
    return street;
  }

  public void setStreet( String street )
  {
    this.street = street;
  }

  public String getCity()
  {
    return city;
  }

  public void setCity( String city )
  {
    this.city = city;
  }

  public String getState()
  {
    return state;
  }

  public void setState( String state )
  {
    this.state = state;
  }
}

The general structure of a whereClause query to load a collection of child objects for a specific parent object is:

ParentTableName[ relatedColumnName ].parentColumnName COLUMN-VALUE-CONDITION

Both columns relatedColumnName and parentColumnName must be declared in a table with name of ParentTableName. The relatedColumnName must be a relation column. The table relatedColumnName points to is the table where the objects must be loaded from.  The examples below demonstrate the usage of this syntax:

Find all contacts in a city for a specific phone book

StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city = 'Smallville'" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city = 'Smallville'" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );

Find all contacts for the specific phone book where the city name contains letter 'a'

StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city like '%a%'" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city like '%a%'" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );

Find all contacts where age is greater than 20 for a specific phone book

StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );

Find all contacts for a specific phone book where age is within the specified range

StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age >= 21 and age <= 30" )

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age >= 21 and age <= 30" )

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );

Find all contacts for a specific phone book where age is greater than 20 and the city is Tokyo

StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20 and address.city = 'Tokyo'" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20 and address.city = 'Tokyo'" );

DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );