簡體   English   中英

App Engine數據存儲區不支持運算符OR

[英]App Engine datastore does not support operator OR

我正在嘗試查詢google數據存儲區(例如pm - > persistanceManager):

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

當我執行時 - 我回來了: App Engine數據存儲區不支持運算符OR

對於這類查詢,人們體驗的最佳方法是什么?

任何幫助贊賞!

執行多個查詢。 與所有其他數據庫一樣,數據存儲區無法有效地執行析取。 與其他數據庫不同,它向用戶暴露了這一難題,明確表示您正在做的事情並不高效。 您唯一的解決方案是執行多個查詢 - 每個查詢一個或 - 並將它們組合在一起。

我不知道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
}

根據Google App Engine - 查詢和索引

查詢過濾器

過濾器指定字段名稱,運算符和值。 該值必須由應用程序提供; 它不能引用其他財產,也不能根據其他財產計算。 運算符可以是以下任何一種: < <= == >= >

注意: Java數據存儲區接口不支持在Python數據存儲區接口中實現的!=和IN過濾器運算符。 (在Python界面中,這些運算符在客戶端庫中實現為多個數據存儲區查詢;它們不是數據存儲區本身的功能。)

過濾器的主題可以是任何對象字段,包括主鍵和實體組父對象(請參閱事務 )。

實體必須將所有過濾器匹配為結果。 在JDOQL字符串語法中,指定了多個過濾器,用&& (邏輯“和”)分隔。 不支持過濾器的其他邏輯組合(邏輯“或”,“非”)。

由於App Engine數據存儲區執行查詢的方式,單個查詢不能在多個屬性上使用不等式過濾器( < <= >= > )。 允許在同一屬性上使用多個不等式過濾器(例如查詢一系列值)。 請參閱查詢限制

基本上,您要么必須重新構建數據,以便您可以通過一個條件或多個“和”條件找到您要查找的內容,或者您​​將不得不通過兩個(或更多)查詢來檢索數據並在您的代碼中過濾/組合它。

對不起,我遲到了。我今天剛遇到你的問題。

“模擬”“IN”和“OR”行為的另一種方法是使用“低級”數據存儲區API。 DatastoreService支持get()方法,該方法接受Keys的集合並返回與傳入的Keys匹配的所有實體的Map。 它是一個接口,但有一個方便的DatastoreServiceFactory可用於分配一個現成的實例。

不幸的是,谷歌決定他們不想推廣這種低級API方法,而是希望開發人員使用JDO或JPA,因此除了JavaDocs以及Google“DatastoreService”時可能找到的任何代碼示例之外,沒有可用的文檔。 。

TL

最新的新聞..至少我只是得到它。 當我下載最新的GAE Java SDK時,我在發行說明中注意到“問題29:暴露批量獲取”在最新版本(v1.2.1)中得到修復。 基本上似乎我們(我正在尋找相同的支持)可能有基於JDO的替代方案,而不是必須下載到“低級”數據存儲API。 我剛剛下載了最新的Java GAE SDK,所以我還沒有機會測試任何東西,但我想盡快給你一個提醒。 在我有機會確認這個“修復”后,我會發布更多信息。

如果我通過重新發布我的評論作為答案來破壞StackOverflow禮儀,請接受我的道歉,但我決定這樣做有兩個原因。 首先是因為,即使我再次解決同一問題,恕我直言這個新信息似乎提供了一個完全不同的問題“答案”。 其次,我擔心在您花費大量時間研究我提供的第一個答案之前,評論表可能不會引起您的注意。

下次我會在演戲前仔細思考。

TL

與cletus的回答相反, OR-ing無論如何都適用於更新版本的App Engine。

實際上,我發現OR-ing在我的App Engine 1.3.0中沒有工作,但是根據Google App Engine - 查詢和索引 (在他的回答中提到的相同來源),

實體必須將所有過濾器匹配為結果。 在JDOQL字符串語法中,您可以使用||分隔多個過濾器 (邏輯“或”)和&&(邏輯“和”),但請記住|| 只有當它分隔的過濾器都具有相同的字段名稱時才能使用它。 換句話說,|| 僅在它分離的過濾器可以組合成單個contains()過濾器的情況下才合法。

我想他的回答(自從我上次更新我的App Engine以來),App Engine必須在此問題上進行升級。

將App Engine更新到1.3.4,OR-ing正常工作! 雖然有限制。

非常感謝cletus :)

您可以使用contains方法

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

簡化必須“自己動手”的一種方法可能是使用參數化查詢:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM