[英]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
}
查詢過濾器
過濾器指定字段名稱,運算符和值。 該值必須由應用程序提供; 它不能引用其他財產,也不能根據其他財產計算。 運算符可以是以下任何一種:
< <= == >= >
注意: 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.