代码之家  ›  专栏  ›  技术社区  ›  JohnIdol

应用程序引擎数据存储不支持操作员或

  •  3
  • JohnIdol  · 技术社区  · 16 年前

    我正在尝试查询Google数据存储,以查找以下内容(使用pm-->PersistenceManager):

    String filters = "(  field == 'value' ||  field == 'anotherValue' )";
    Query query = pm.newQuery(myType.class, filters);
    

    当我执行-我回来: 应用程序引擎数据存储不支持操作员或 .

    对于这种查询,人们体验的最佳方法是什么?

    感谢您的帮助!

    8 回复  |  直到 16 年前
        1
  •  10
  •   Nick Johnson    16 年前

    执行多个查询。与所有其他数据库一样,数据存储无法有效地执行分离。与其他数据库不同,它向用户暴露了这一困难,以清楚地表明您所做的工作是不高效的。您唯一的解决方案是执行多个查询-每个查询一个或-并组合它们。

        2
  •  4
  •   tetsuo    15 年前

    我不知道GAE的JDO和JPA实现是否支持这一点,但是使用低级API,您可以在一个查询中为此使用中的运算符。

    Query query = new Query("Issue");
    List<String> list = Arrays.asList("NEW", "OPEN", "ACCEPTED");
    query.addFilter("status", FilterOperator.IN, list);
    
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    PreparedQuery preparedQuery = datastore.prepare(query);
    for (Entity entity : preparedQuery.asIterable()) {
        // should iterate over 'NEW', 'OPEN' and 'ACCEPTED' issues
    }
    
        3
  •  2
  •   cletus    16 年前

    根据 Google App Engine - Queries and Indexes :

    查询过滤器

    滤波器 指定字段名, 一个运算符和一个值。价值 必须由应用程序提供;不能 指其他财产,或 按其他方式计算 性质。操作员可以是 下列内容: < <= == >= >

    注: Java数据存储接口不支持!=和 滤波器中 在中实现的运算符 python数据存储接口。(在 python接口,这些操作符是 在客户端实现 库作为多个数据存储 查询;它们不是 数据存储本身。)

    过滤器的主题可以是任何 对象字段,包括主字段 键和实体组父级(请参见 Transactions )

    实体必须匹配所有要 结果。在jdoql字符串语法中, 指定了多个筛选器 分开 && (逻辑“and”)。 过滤器的其他逻辑组合 (逻辑“或”、“非”)不是 支持。

    由于应用程序引擎的方式 数据存储执行查询,一个 查询不能使用不等式筛选器 ( < <= >= > )在多个 财产。多重不等式滤波器 在同一属性上(例如查询 对于一系列值)是允许的。 见 Restrictions on Queries .

    基本上,你要么重组你的数据,这样你就可以在一个条件或多个“和”条件下找到你想要的,要么你必须通过两个(或更多)查询来检索数据,并在你的代码中过滤/组合它。

        4
  •  1
  •   Thomas Lukasik    16 年前

    对不起,我迟到了……我今天刚碰到你的问题。

    “模拟”in“和”or“行为的另一种方法是使用“低级”数据存储API。datastoreService支持get()方法,该方法接受键的集合,并返回与传入键匹配的所有实体的映射。它是一个接口,但有一个方便的datastoreservicefactory可用,它将分配一个随时可用的实例。

    不幸的是,谷歌决定他们不想推广这种低级的API方法,而更倾向于开发人员使用JDO或JPA,因此除了javadocs和在谷歌“datastoreservice”时可能找到的任何代码示例之外,没有其他文档可用。

        5
  •  1
  •   Thomas Lukasik    16 年前

    最新消息……至少我刚拿到。当我为GAE下载最新的Java SDK时,我注意到发行版上的“发布29:公开批量获取”被固定在最新版本(V1.2.1)中。基本上,我们(我正在寻找与之相同的支持)可能有一个基于JDO的替代方案,而不是必须降到“低级”数据存储API。我刚刚下载了最新的Java GAE SDK,所以我还没有机会测试任何东西,但我想尽快给大家一个提示。在我有机会确认这个“修复”之后,我会发布更多我学到的东西。

    如果我违背了StackOverflow的礼节,请接受我的道歉,我将我的评论重新发布作为答案,但我决定这样做有两个原因。首先,因为,即使是我再次处理同一个问题,imho这个新的信息似乎为这个问题提供了一个完全不同的“答案”。其次,我担心在你花大量时间研究我提供的第一个答案之前,评论表可能不会引起你的注意。

    下次在演戏前我会仔细考虑的。

        6
  •  0
  •   Peter Recore    16 年前

    简化“自己动手”的一种方法可能是使用参数化查询:

       Query query = pm.newQuery(mytype.class);
       query.setFilter("field == autoParam");
       query.declareParameters("String autoParam");
    
       List<String> params = myListOfThingsFieldCanBeEqualTo;
    
       Set merged = new HashSet();
       for (String f : params) {
         merged.addAll(q.execute(f));
       }
    
        7
  •  0
  •   Jiwon Park    15 年前

    与克莱特斯的回答相反, 或ING作品 在应用引擎的最新版本中。

    事实上,我发现或者不在应用引擎1.3.0中工作,但是根据 Google App Engine - Queries and Indexes (他的回答中提到的同一个来源克莱图斯)

    实体必须匹配所有筛选器才能成为结果。在JDOQL字符串语法中,可以使用(逻辑“or”)和&&(逻辑“and”)分隔多个筛选器,但请记住,只有当它分隔的所有筛选器具有相同的字段名时,才能使用。换句话说,只有在它分离的过滤器可以组合成单个contains()过滤器的情况下才是合法的。

    我想,自从他的回答(和我上次更新我的应用引擎),应用引擎一定是升级了这件事。

    将应用程序引擎更新为1.3.4,否则将正常工作! 尽管有限制。

    不管怎样,多亏了克莱特斯:)

        8
  •  0
  •   benliet    10 年前

    您可以使用包含方法

    String filters = "( :values.contains(field) )";
    Query query = pm.newQuery(myType.class, filters);