Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objectify - How to filter by boolean?

I've hit a wall using Objectify for the google appengine datastore when filtering on boolean values. This is roughly what I've:

class Task implements Serializable {
 ... 
 boolean failed;
 ...
}

No matter what i do when i search, i always get an empty response although there are objects in the db that has failed = false

Examples:

ofy().query(Task.class).filter("failed",false).list()
ofy().query(Task.class).filter("failed",Boolean.FALSE).list()
ofy().query(Task.class).filter("failed",0).list()
ofy().query(Task.class).filter("failed","false").list()
ofy().query(Task.class).filter("failed","FALSE").list()
like image 380
Anders Avatar asked Sep 20 '26 12:09

Anders


2 Answers

I found this old question while Googling and I wanted to clear it up.

You should be able to query by boolean fields as long as they are indexed at the time that they entered the datastore. Here's a complete unit test using Objectify and the App Engine unit test library (To run it, you have to link in the unit test jar described here). The following test passes. So the problem lies elsewhere, and I suggest that you use unit tests to discover it.

import static org.junit.Assert.*;

import javax.persistence.Id;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.QueryResultIterator;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

class FakeEntity {
  @Id public Long id;
  public boolean boolProp;
  public boolean equals(Object other) {
    return other != null &&
           other instanceof FakeEntity &&
           ((FakeEntity)other).id == this.id &&
           ((FakeEntity)other).boolProp == this.boolProp; 
  }
}

public class FakeEntityTest {
  private final LocalServiceTestHelper helper =
    new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
  @Before
  public void setUp() {
    helper.setUp();
  }
  @After
  public void tearDown() {
    helper.tearDown();
  }

  @Test
  public void testBoolQuery() {
    ObjectifyFactory objectifyFactory = ObjectifyService.factory();
    objectifyFactory.register(FakeEntity.class);
    Objectify objectify = objectifyFactory.begin();
    FakeEntity entityFalse = new FakeEntity();
    FakeEntity entityTrue = new FakeEntity();
    entityTrue.boolProp = true;
    objectifyFactory.begin().put(entityFalse);
    objectifyFactory.begin().put(entityTrue);

    assertArrayEquals(
        new FakeEntity[] {entityFalse},
        objectify.query(FakeEntity.class)
        .filter("boolProp", false).list().toArray());
    assertArrayEquals(
        new FakeEntity[] {entityTrue},
        objectify.query(FakeEntity.class)
        .filter("boolProp", true).list().toArray());
    assertArrayEquals(
        new FakeEntity[] {entityTrue},
        objectify.query(FakeEntity.class)
        .filter("boolProp", true).list().toArray());
    assertArrayEquals(
        new FakeEntity[] {entityTrue},
        objectify.query(FakeEntity.class)
        .filter("boolProp", Boolean.TRUE).list().toArray());
    // Filtering on integers and strings WON'T work:
    assertArrayEquals(
        new FakeEntity[] {},
        objectify.query(FakeEntity.class)
        .filter("boolProp", "true").list().toArray());
    assertArrayEquals(
        new FakeEntity[] {},
        objectify.query(FakeEntity.class)
        .filter("boolProp", 0).list().toArray());
  }
}
like image 92
yonran Avatar answered Sep 22 '26 01:09

yonran


You haven't Indexed boolean failed property.

If a field is not indexed, filter will not work in objectify datastore.

So to make it work, add

@Index boolean failed;

Now your filter will work.

Please note that though indexed, already saved values cannot be filtered. So either create new records and save or read all datastore entities and save it again.

Hope this helps.

like image 25
Bharathi Avatar answered Sep 22 '26 00:09

Bharathi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!