Objectify - 如何按布尔值过滤?

发布于 2024-09-16 08:28:52 字数 549 浏览 1 评论 0 原文

在过滤布尔值时,我在使用 Google AppEngine 数据存储的 Objectify 时遇到了困难。这大致就是我的情况:

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

无论我在搜索时做什么,尽管数据库中存在 failed = false 的对象,但我总是得到空响应

示例:

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()

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

衣神在巴黎 2024-09-23 08:28:52

我在谷歌搜索时发现了这个老问题,我想澄清它。

您应该能够通过布尔字段进行查询,只要它们在进入数据存储时已建立索引即可。以下是使用 Objectify 和 App Engine 单元测试库的完整单元测试(要运行它,您必须链接到 此处描述的单元测试 jar)。以下测试通过。所以问题出在其他地方,我建议你使用单元测试来发现它。

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());
  }
}

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());
  }
}
零度℉ 2024-09-23 08:28:52

您尚未对布尔失败属性建立索引。

如果字段未建立索引,过滤器将无法在 objectify 数据存储中工作。

因此,要使其发挥作用,请添加“

@Index boolean failed;

现在您的过滤器将起作用”。

请注意,虽然已建立索引,但无法过滤已保存的值。因此,要么创建新记录并保存,要么读取所有数据存储实体并再次保存。

希望这有帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文