Могу ли я выполнить один запрос на выборку, который возвращает независимые вычисления для подмножеств результатов?

Моя модель данных имеет сущность ClickerRecord с 2 атрибутами: дата (NSDate) и numberOfBiscuits (NSNumber). Каждый раз, когда добавляется новая запись, можно ввести другое значение для numberOfBiscuits.

Чтобы рассчитать среднесуточное количество печенья, я делаю запрос на выборку для каждого дня в пределах диапазона и использую соответствующий NSExpression рассчитать сумму всех значений numberOfBiscuits за этот день.

Проблема: я использую асинхронные запросы на выборку, чтобы избежать блокировки основного потока, поэтому он оказывается довольно медленным, когда между первой и последней записью много дней. Запросы на выборку выполняются один за другим. Я также мог бы загрузить все записи в память и выполнить сортировку и вычисления, но я боюсь, что это может стать проблемой, когда количество записей станет очень большим.

Поэтому мой вопрос: возможно ли использовать NSExpressions для добавления чего-то вроде предикатов для каждого интервала дат, чтобы выполнить один запрос на выборку и получить словарь с записью для каждой ежедневной суммы numberOfBiscuits? Если нет, какой будет рекомендуемый подход в этой ситуации?

Я читал о подзапросах, но, насколько я понял, они не предназначены для такого использования.

Это первый вопрос, который я задаю на SO, так что я надеюсь, что написал это ясно:)

1 ответ

Решение

Я думаю, что вы ищете propertiesToGroupBy (см. Apple Docs) для NSFetchRequestХотя в вашем случае это не так просто для реализации, по причинам, которые я буду обсуждать позже.

Предположим, вы можете указать категорию печенья, потребляемого в каждом случае, и это хранится в category атрибут вашей сущности. Затем, чтобы получить общее количество печенья каждой категории (без учета даты), вы можете использовать NSExpression с помощью @sum и укажите:

fetch.propertiesToGroupBy = ["category"]

Затем CoreData сгруппирует результаты выборки по category и рассчитает сумму для каждой группы отдельно.

Проблема в вашем случае заключается в том, что (если вы уже не удаляете информацию о времени из вашего date атрибута), нет атрибута, представляющего интервал даты, по которому вы хотите группировать данные, и CoreData не позволит вам указать вычисляемое значение для группировки. Вам нужно будет добавить новый day приписать свою сущность, и вычислить это всякий раз, когда вы добавляете / обновляете запись, и указываете ее в группе по. И вы снова столкнетесь с той же проблемой, если впоследствии захотите рассчитать свое среднее значение за другой интервал - например, недели или месяцы. Еще одним недостатком является то, что результаты будут включать только days для которых есть ClickerRecords: если у пользователя есть день, когда он не потребляет печенье, то выборка не будет показывать результат за этот день (то есть не будет выводить в среднем 0). Вы должны будете обращаться с этим соответствующим образом при использовании результатов.

Может быть, лучше либо настроить асинхронную выборку, либо, как вы предлагаете, просто записать весь лот в память для выполнения вычислений. Если ваша сущность имеет только эти два атрибута и при условии, что ваши пользователи не живут исключительно печеньем, объемы не должны быть слишком проблематичными.

Другие вопросы по тегам