2016-02-21 1 views
0

Предположим, что ниже мое содержание Datastore в Google Cloud Platform:"SQL Group By" Альтернатива для Datastore в Google Cloud Platform

enter image description here

class ItemRecord { 
    @Id 
    private 
    Long id; 

    @Index 
    private String item; 
    @Index 
    private String user; 
    @Index 
    private int minValue; 
    @Index 
    private int maxValue; 
} 

Я хочу, чтобы получить Minumum из minValue и максимум maxValue значения для item групп:

item1 minumum_minValue= 1, maximum_maxValue= 13 
item2 minumum_minValue= 3, maximum_maxValue= 10 

Примечание: Свойства minValue и maxValue являются обновляемыми (сущности представляют собой заданные пользователем значения, и пользователь может обновлять их в любое время), поэтому, пожалуйста, рассмотрите обновление, удаление операций, если вы собираетесь предложить использовать отдельный объект для хранения минимальной суммы minValue и максимум от maxValue значений.

Я искал что-то вроде ниже SQL:

SELECT item, MAX(maxValue) 
FROM [ItemRecord] 
Group by item 

и

SELECT item, MIN(minValue) 
FROM [ItemRecord] 
Group by item 

Но Datastore не поддерживает «группы по» операции, и я не мог найти что-нибудь подобное для него.

Итак, как я решил проблему?

1) получить уникальные имена элементов:

private static List<String> getDistinctItemNameList() { 
    Query query = ofy().load().type(ItemRecord.class) 
      .project("item").distinct(true); 
    List<ItemRecord> resultList = query.list(); 

    if(resultList != null && !resultList.isEmpty()) { 
     List<String> itemNameList = new ArrayList<>(resultList.size()); 
     for (ItemRecord itemRecord : resultList) { 
      itemNameList.add(itemRecord.getItem()); 
     } 
     return itemNameList; 
    } 
    return null; 
} 

2) Для каждого ITEMNAME (который извлекается выше) датасторе запроса для его Minumum MinValue и максимальной MaxValue:

private ItemRecord getMinumumMinValue(String itemName) { 
    ItemRecord record = ofy() 
      .load() 
      .type(ItemRecord.class) 
      .filter("item", itemName) 
      .order("minValue") 
      .first().now(); 

    return record; 
} 

private ItemRecord getMaximumMaxValue(String itemName) { 
    ItemRecord record = ofy() 
      .load() 
      .type(ItemRecord.class) 
      .filter("item", itemName) 
      .order("-maxValue") 
      .first().now(); 

    return record; 
} 

Стоимость: (запрос на получение отдельных имен элементов) + (отдельный счетчик элементов * для минимального значения minValue) + (отдельный счетчик элементов * запрос fo r max maxValue)

Но это решение очень раздражает своими многочисленными операциями чтения. Есть ли у вас предложение, лучшее решение?

ответ

2

Хранилище данных является плохим инструментом для аналитических запросов. Реплицируйте подмножество данных в Cloud SQL или в другое реляционное хранилище, которое может легко выполнять агрегации.

+0

Спасибо. Интересно, является ли текущая стоимость моего вопроса лучшей ценой? Или какие-то альтернативы? (Я хочу продолжить с хранилищем данных, потому что он бесплатный, и я не хочу платить деньги за Cloud SQL на данный момент). – Devrim

+0

Рассмотрите возможность использования BigQuery, это не бесплатно, а для небольшого набора данных (исходя из вашего ответа, вы свободны уровень) будет грязным. – Barak

Смежные вопросы