Поиск объектов в Базовых Данных по атрибуту массива, эффективно в> 10k элементах - PullRequest
2 голосов
/ 17 января 2011

Short:
Мне нужно найти объекты основных данных по ключу, который содержит уникальный неизменяемый массив (фиксированной длины, но выбран во время выполнения) произвольных объектов (для которых не только элемент ) членство , а также порядок элементов определяет уникальность ). NSManagedObject однако запрещает переопределение [isEqual:]. И что теперь?


Long:
У меня есть сущность (см. Изображение диаграммы для сущности «… Link») в моей модели базовых данных, для которой я должен гарантировать уникальность на основе ключа атрибута («кортеж»). Пока все хорошо.

Уникальный атрибут объекта должен быть NSArray .
И чтобы сделать все немного сложнее, я также не знаю тип класса элементов кортежа .
Также я не знаю количество элементов в кортеже. Ну, на самом деле, количество одинаково для каждого кортежа (по крайней мере, для каждого контекста данных), но не известно до запуска приложения.

Должен быть только один экземпляр моего объекта ссылки с заданным кортежем .
И по очевидной причине только один экземпляр кортежа с заданным массивом произвольных объектов.
Принимая во внимание, что два кортежа должны считаться равными, если [tuple_1 isEqual:tuple_n] возвращает YES. NSManagedObject запрещает переопределение из [isEqual:] и [hash], хотя в противном случае все было бы довольно просто.

Объекты «… Tuple» создаются вместе с их массивом токенов (с помощью удобного метода), а являются неизменяемыми (как и каждый «… Token» и его атрибут данных ). (Думайте о «… Tuple» как о словарном ключе «… Link».)

"… Tuple" реализует "- (NSArray *)tokens;", который возвращает аккуратно упорядоченный массив токенов , основанный на ключах "order" в "... TokenOrder". ( Кортежи , как ожидается, содержат не более 5 элементов .)

Я, однако, ожидаю иметь десятки тысяч (потенциально даже больше в некоторых крайних случаях) объектов "… Link", которые я должен (часто) найти, основываясь на их "кортеже" атрибут .

К сожалению, я не смог найти ни одной статьи (не говоря уже о решении) для такого сценария ни в одной литературе или в Интернете.

Есть идеи?

core data model

Возможное решение, которое я придумала до сих пор:

  1. Узкое количество элементов для сравнения кортежем, добавив еще один атрибут на «… кортеж» под названием «tupleHash», который предварительно рассчитан на создание объекта через: Фрагмент 1

  2. Запрос с NSPredicate для объектов, соответствующих tupleHash (немного сужает список кандидатов).

  3. Найдите «… Link» с указанным кортежем в суженном списке кандидатов по: Snippet 1

Фрагмент 1:

NSUInteger tupleHash = [[self class] hash];
for (id token in self.tokens) {
    tupleHash ^= [token.data hash];
}

Фрагмент 2:

__block NSArray *tupleTokens = someTokens;
NSArray *filteredEntries = [narrowedCandidates filteredArrayUsingPredicate:
  [NSPredicate predicateWithBlock: ^(id evaluatedObject, NSDictionary *bindings) {
    return [evaluatedObject.tuple.tokens isEqualToArray:tupleTokens];
}]];

(Извините, похоже, что уценка препятствует смешиванию списков с фрагментами кода.)

Хорошая идея или просто безумие?

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 17 января 2011

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

Обновление:

Вам не нужно использовать метод хэширования NSArray.Чтобы вычислить хеш, вы можете выполнить SHA1 или MD5 для конкатенации значений массива.Существует много алгоритмов хеширования, их всего два.

Вы можете создать категорию для NSArray, скажем myHash, чтобы сделать код многократно используемым.

0 голосов
/ 19 января 2011

Как рекомендовано в комментарии Джо Блоу Я просто собираюсь перейти на SQLite.Базовые данные здесь просто кажутся неправильным инструментом.

Преимущества:

  • Быстрая благодаря индексации столбцов SQL
  • Нет выделения / инициализации объекта в SELECT довозвращая результаты.(какие базовые данные потребуются для проверки атрибутов)
  • Простой запрос кортежей ссылок с помощью JOIN.
  • Простое использование SQLite JOIN, GROUP BY, ORDER BY и т. д.
  • Little toнет кода обертки благодаря EGODatabase ( FMDB обернутая оболочка SQLite Objective-C)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...