App Engine 数据存储区不支持运算符 OR

发布于 2024-07-21 12:35:11 字数 325 浏览 14 评论 0 原文

我正在尝试查询 google 数据存储以获取类似的内容(使用 pm --> persistanceManager):

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

当我执行时 - 我返回:App Engine 数据存储不支持运算符 OR

人们对于此类查询的最佳体验是什么?

任何帮助表示赞赏!

I am trying to query the google datastore for something like (with pm --> persistanceManager):

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

When I execute - I am getting back: App Engine datastore does not support operator OR.

What's the best approach in people experience for this kind of queries?

Any help appreciated!

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

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

发布评论

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

评论(8

冰葑 2024-07-28 12:35:11

根据 Google App Engine - 查询和索引

查询过滤器

过滤器指定字段名称,
一个运算符和一个值。 价值
必须由应用程序提供; 这不可以
引用另一个属性,或者是
以其他方式计算
特性。 运算符可以是以下任意一个
以下:<代码>< <= == >= >

<块引用>

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

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

实体必须匹配所有过滤器才能
一个结果。 在 JDOQL 字符串语法中,
指定了多个过滤器
&&(逻辑“与”)分隔。
过滤器的其他逻辑组合
(逻辑“或”、“非”)不是
支持。

由于App Engine的方式
数据存储执行查询,单个
查询不能使用不等式过滤器
(<<<=>=>) 多个
财产。 多重不等式过滤器
在同一个属性上(例如查询
对于一系列值)是允许的。
请参阅查询限制

基本上,您要么必须重组数据,以便可以使用一个条件或多个“and”条件找到您要查找的内容,要么必须通过两个(或更多)查询检索数据并将其过滤/组合到您的代码中。

According to Google App Engine - Queries and Indexes:

Query Filters

A filter specifies a field name,
an operator, and a value. The value
must be provided by the app; it cannot
refer to another property, or be
calculated in terms of other
properties. The operator can be any of
the following: < <= == >= >

Note: The Java datastore interface does not support the != and
IN filter
operators that are implemented in the
Python datastore interface. (In the
Python interface, these operators are
implemented in the client-side
libraries as multiple datastore
queries; they are not features of the
datastore itself.)

The subject of a filter can be any
object field, including the primary
key and the entity group parent (see
Transactions).

An entity must match all filters to be
a result. In the JDOQL string syntax,
multiple filters are specified
separated by && (logical "and").
Other logical combinations of filters
(logical "or", "not") are not
supported.

Due to the way the App Engine
datastore executes queries, a single
query cannot use inequality filters
(< <= >= >) on more than one
property. Multiple inequality filters
on the same property (such as querying
for a range of values) are permitted.
See Restrictions on Queries.

Basically you're either going to have to restructure your data so that you can find what you're looking for with one condition or multiple "and" conditions or you're going to have to retrieve the data via two (or more) queries and filter/combine it in your code.

酷遇一生 2024-07-28 12:35:11

执行多个查询。 与所有其他数据库一样,数据存储区无法有效地执行析取。 与其他数据库不同,它向用户暴露了这种困难,以表明您正在做的事情效率不高。 您唯一的解决方案是执行多个查询 - 每个查询一个或 - 并将它们组合起来。

Perform multiple queries. The Datastore, like all other databases, isn't able to efficiently execute disjunctions. Unlike other databases, it exposes this difficulty to the user, to make it clear that what you're doing isn't efficient. Your only solution is to execute multiple queries - one for each or - and combine them.

魔法唧唧 2024-07-28 12:35:11

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

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
}

I don't know if GAE's JDO and JPA implementations support this, but using the low-level API, you can use the operator IN for this, in one query.

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
}
没有心的人 2024-07-28 12:35:11

抱歉,我迟到了。我今天才遇到你的问题。

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

不幸的是,Google 决定他们不想推广这种低级 API 方法,而更喜欢开发人员使用 JDO 或 JPA,因此除了 JavaDoc 以及 Google“DatastoreService”时可能找到的任何代码示例之外,没有任何可用的文档。 。

TL

Sorry I'm late to the game.. I just ran across your question today.

Another way to "simulate" 'IN' and 'OR' behavior is to use the "low level" Datastore API. The DatastoreService supports a get() method that accepts a collection of Keys and returns a Map of all Entities that matched the passed in Keys. It's an interface, but there's a handy DatastoreServiceFactory available that will dispense a ready-to-use instance.

Unfortunately, Google decided that they don't want to promote this low-level API approach and prefer that developers use JDO or JPA, so there's no documentation available other than the JavaDocs and whatever code samples that you might find when you Google "DatastoreService".

TL

汹涌人海 2024-07-28 12:35:11

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

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

One way to simplify having to "do it yourself" might be to use parameterized queries:

   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));
   }
莫相离 2024-07-28 12:35:11

最新消息……至少我刚刚得到它。 当我下载最新的 GAE Java SDK 时,我在发行说明中注意到“问题 29:公开批处理获取”已在最新版本 (v1.2.1) 中修复。 基本上,我们(我正在寻找似乎相同的支持)可能有一个基于 JDO 的替代方案,而不必下降到“低级”数据存储 API。 我刚刚下载了最新的 Java GAE SDK,因此还没有机会测试任何内容,但我想尽快给您一个提示。 在我有机会确认这个“修复”之后,我将发布我学到的更多内容。

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

下次我会在行动前仔细考虑一下。

TL

Late breaking News.. at least I'm just getting it. As I was downloading the latest Java SDK for GAE I noticed on the Release Notes that "Issue 29: Expose batch gets" was fixed in the latest release (v1.2.1). Basically it seems that we (I'm looking for the same support it seems) may have a JDO based alternative rather than having to drop down to the "low-level" Datastore API. I've just downloaded the latest Java GAE SDK so I haven't had an opportunity to test anything yet, but I wanted to give you a heads-up ASAP. I'll post anything more I learn after I've had a chance to confirm this "fix".

Please accept my apologies if I've broken StackOverflow etiquette by re-posting my comment as an answer, but I decided to do it for two reasons. Firstly because, even though it's me addressing the same issue again, IMHO this new information appears to provide a completely different "answer" to the problem. And secondly, I was concerned that the comment form might not get your attention before you'd spent a great deal of time looking into the first answer that I provided.

Next time I'll think more carefully before acting.

TL

晨敛清荷 2024-07-28 12:35:11

您可以使用 contains 方法

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

You can use the contains method

String filters = "( :values.contains(field) )";
Query query = pm.newQuery(myType.class, filters);
北方。的韩爷 2024-07-28 12:35:11

与 cletus 的答案相反,OR-ing 有效,无论如何,在最新版本的 App Engine 中。

事实上,我发现 OR-ing 在我拥有的 App Engine 1.3.0 中不起作用,但根据 Google App Engine - 查询和索引(与他的答案中提到的相同来源 cletus),

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

我想自从他的回答(以及自从我上次更新我的 App Engine 以来),App Engine 一定已经在这个问题上进行了升级。

将 App Engine 更新到 1.3.4,OR 运算就可以工作!尽管有限制。

无论如何,都要感谢 cletus:)

Contrary to cletus' answer, OR-ing works, in more recent version of App Engine anyway.

Indeed, I found OR-ing not working in App Engine 1.3.0 that I had, but according to Google App Engine - Queries and Indexes (the same source cletus referred to in his answer),

An entity must match all filters to be a result. In the JDOQL string syntax, you can separate multiple filters with || (logical "or") and && (logical "and"), although keep in mind that || can only be employed when the filters it separates all have the same field name. In other words, || is only legal in situations where the filters it separates can be combined into a single contains() filters.

I figured since his answer (and since I last updated my App Engine), App Engine must have been upgraded on this matter.

Update App Engine to 1.3.4, and the OR-ing works! Though with the limitation.

Thanks to cletus anyway:)

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