Поисковые задачи набора

Эта глава обеспечивает инструкции и примеры кода для общих Поисковых задач Набора включая создание и использование индексов различных типов, выполнение поисков и отображение результатов.

Примеры кода предполагают использование XCode, и они иллюстрируют, как использовать ANSI-C Поискового Набора API в методах Objective C.

Используя индексы и документы

Для индексации документа приложение сначала создает пустой индекс и затем добавляет содержание документа к нему. Поисковые индексы Набора имеют множество характеристик, которые можно установить во время создания индекса. Эти характеристики определяют такие вещи, как которые типы пользователей поисков могут выполнить.

Ваше приложение может создать основанные на файле или основанные на памяти индексы. Используйте основанные на файле индексы для получения информации, которую Вы хотите сохранить между вызовами Вашей программы. Используйте основанные на памяти индексы для временных процессов, таких как поиск на подмножестве основанного на файле индекса. Поскольку основанные на памяти индексы могут быть открыты как только для чтения, а также чтение-запись, можно использовать основанный на памяти индекс, когда для приложения нужен индекс, который открыт только для поиска.

При создании индекса, или основанного на файле или основанного на памяти, индекс автоматически открыт. Поисковые функции Набора для открытия индексов позволяют Вашему приложению вновь открыть индекс, который Вы закрыли или открываете ранее создаваемый основанный на файле индекс.

Создание основанного на файле индекса

Для создания персистентного, основанного на файле индекса приложение должно только предоставить расположение файловой системы в форме объекта CFURL и надлежащем постоянном указании типа индекса, который Вы хотите. Если Вы разрабатываете в Какао, можно использовать объект NSURL для индексного расположения и бросить его к объекту CFURLRef как показано в Перечислении 3-1.

Для создания индекса в памяти посмотрите Создание Индекса в Памяти. Для указания свойств анализа текста для индекса посмотрите Указание Свойств Анализа текста.

Перечисление 3-1  , Создающее основанный на файле индекс

- (void) newIndexInFile {
    NSString *path = [pathTextField stringValue];     // 1
    NSURL *url = [NSURL fileURLWithPath: path];       // 2
 
    NSString *name = [nameTextField stringValue];     // 3
    if ([name length] == 0) name = nil;
 
    SKIndexType type = kSKIndexInverted;              // 4
 
    mySKIndex = SKIndexCreateWithURL (                // 5
        (CFURLRef) url,
        (CFStringRef) name,
        (SKIndexType) type,
        (CFDictionaryRef) NULL
    );
}

Вот то, как работает этот код:

  1. Получает путь файловой системы для нового основанного на файле индекса и преобразовывает его в объект NSString.

  2. Преобразовывает объект NSString в объект NSURL.

  3. Получает дополнительное имя индекса, если предоставленный, и сохраняет его в объекте NSString. Если нет никакого имени индекса, использования nil.

  4. Определяет индексный тип, в этом случае, указывающем инвертированный индекс.

  5. Создает новый, пустой, основанный на файле индекс с помощью указанного URL, имени и типа. Возвращает Поисковый индексный объект Набора. В этом простом примере код создает индекс, не указывая словарь свойств анализа текста. Посмотрите Указание Свойств Анализа текста для получения дополнительной информации об использовании словаря свойств анализа текста.

Создание индекса в памяти

Для создания индекса в памяти приложение предоставляет NSMutableData объект (или, эквивалентно, a CFMutableDataRef объект) для содержания индекса. Перечисление 3-2 показывает как.

Перечисление 3-2  , Создающее индекс в памяти

- (void) newIndexInMemory {
    NSString *name = [nameTextField stringValue];               // 1
    if ([name length] == 0) name = nil;
 
    SKIndexType type = kSKIndexInverted;                        // 2
 
    indexObject = [[NSMutableData alloc] initWithCapacity: 0];  // 3
 
    mySKIndex = SKIndexCreateWithMutableData (                  // 4
                    (CFMutableDataRef) indexObject,
                    (CFStringRef)      name,
                    (SKIndexType)      type,
                    (CFDictionaryRef)  NULL
                );
}

Вот то, как работает этот код:

  1. Получает дополнительное имя индекса, если предоставленный, и сохраняет его в объекте NSString. Если нет никакого имени индекса, использования nil.

  2. Определяет индексный тип, в этом случае, указывающем инвертированный индекс.

  3. Создает непостоянный объект данных содержать новый основанный на памяти индекс.

  4. Создает новый, пустой, основанный на памяти индекс с помощью предоставленного непостоянного объекта данных, имени и типа. Возвращает Поисковый индексный объект Набора. В этом простом примере код создает индекс, не указывая словарь свойств анализа текста. Посмотрите Указание Свойств Анализа текста для получения дополнительной информации об использовании словаря свойств анализа текста.

Чтобы вместо этого создать индекс в файле посмотрите Создание Основанного на файле Индекса.

Открытие основанного на файле индекса для поиска или обновления

Чтобы работать с уже существующим основанным на файле индексом (тот, существовавший перед, Ваше приложение запустилось) или работать с тем, который Вы явно закрыли, Ваше приложение должно сначала открыть его. Один раз открытый, основанный на файле Поисковый индекс Набора может искаться или обновляться.

Основанные на памяти индексы могут быть открыты в режиме только для чтения, а также в режиме чтения-записи. Посмотрите Открытие Основанного на памяти Индекса для Поиска Только и Открытия Основанного на памяти Индекса для Поиска или Обновления.

Перечисление 3-3  , Открывающее основанный на файле индекс для поиска или обновления

- (void) openIndex {
    NSString *path = [pathTextField stringValue];      // 1
    NSURL *url = [NSURL fileURLWithPath:path];         // 2
 
    NSString *name = [nameTextField stringValue];      // 3
    if ([name length] == 0) name = nil;
 
    // open the specified index
   mySKIndex = SKIndexOpenWithURL (                    // 4
                   (CFURLRef) url,
                   (CFStringRef) name,
                   true
                );
}

Вот то, как работает этот код:

  1. Получает путь файловой системы для существующего основанного на файле индекса и преобразовывает его в объект NSString.

  2. Преобразовывает путь объект NSString в объект NSURL.

  3. Получает имя индекса, если предоставленный, для существующего основанного на файле индекса и сохраняет его как объект NSString. Если нет никакого имени индекса, использования nil.

  4. Открывает основанный на файле индекс и возвращает Поисковый индексный объект Набора.

Открытие основанного на памяти индекса для поиска только

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

Эта задача описывает, как открыть основанный на памяти индекс для поиска только. Для открытия основанного на памяти индекса для поиска или обновления посмотрите Открытие Memory-Based Index for Searching или Updating.

Перечисление 3-4  , Открывающее основанный на памяти индекс для поиска только

- (void) openIndexInMemoryReadOnly {
    mySKIndex = SKIndexOpenWithData (
                   (CFDataRef)   indexObject,
                   (CFStringRef) nil
               );
}

Вот то, как работает этот код:

Ваше приложение обеспечивает ранее создаваемый непостоянный объект данных для SKIndexOpenWithData функция, тогда возвращающая Поисковый индексный объект Набора только для чтения. Имя индекса является дополнительным, и в этом примере указан как nil. Для открытия основанного на памяти индекса для поиска и обновления посмотрите Открытие Memory-Based Index for Searching или Updating. Для получения информации о создании непостоянного объекта данных посмотрите Создание Индекса в Памяти.

Открытие основанного на памяти индекса для поиска или обновления

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

Эта задача описывает, как открыть основанный на памяти индекс для поиска или обновления. Для открытия основанного на памяти индекса для поиска только посмотрите Открытие Memory-Based Index for Searching Only.

Перечисление 3-5  , Открывающее основанный на памяти индекс для поиска или обновления

- (void) openIndexInMemoryReadWrite {
    mySKIndex = SKIndexOpenWithMutableData (
                   (CFMutableDataRef) indexObject,
                   (CFStringRef)      nil
                );
}

Вот то, как работает этот код:

Ваше приложение обеспечивает ранее создаваемый непостоянный объект данных для SKIndexOpenWithMutableData функция, тогда возвращающая индексный объект Набора Поиска чтения-записи. Имя индекса является дополнительным, и в этом примере указан как nil. Для открытия основанного на памяти индекса для поиска только посмотрите Открытие Memory-Based Index for Searching Only. Для получения информации о создании непостоянного объекта данных посмотрите Создание Индекса в Памяти.

Закрытие индекса

Поисковый индекс Набора, как Базовый объект Основы, может быть закрыт путем передачи индексного объекта CFRelease функция. Также Ваше приложение может использовать SKIndexClose функционируйте как показано здесь.

Перечисление 3-6  , Закрывающее индекс

- (void) closeIndex {
    if (mySKIndex) {
        SKIndexClose (mySKIndex);
        mySKIndex = nil;
    }
}

Указание свойств анализа текста

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

Перечисление 3-7  , Указывающее свойства анализа текста

- (void) newIndexWithPropertiesInFile {
    NSString *path = [pathTextField stringValue];                // 1
    NSURL *url = [NSURL fileURLWithPath: path];                  // 2
 
    NSString *name = [nameTextField stringValue];                // 3
    if ([name length] == 0) name = nil;
 
    SKIndexType type = kSKIndexInverted;                         // 4
 
    NSNumber *minTermLength = [NSNumber numberWithInt: (int) 3]; // 5
 
    NSSet *stopwords = [NSSet setWithObjects:                    // 6
                            @"all",
                            @"and",
                            @"its",
                            @"it's",
                            @"the",
                            nil
                        ];
 
        NSDictionary *properties =                               // 7
        [NSDictionary dictionaryWithObjectsAndKeys:
            @"", @"kSKStartTermChars",   // additional starting-characters for terms
            @"-_@.'", @"kSKTermChars",   // additional characters within terms
            @"", @"kSKEndTermChars",     // additional ending-characters for terms
            minTermLength, @"kSKMinTermLength",
            stopwords, @"kSKStopWords",
            nil
        ];
 
    mySKIndex = SKIndexCreateWithURL(                            // 8
        (CFURLRef) url,
        (CFStringRef) name,
        (SKIndexType) type,
        (CFDictionaryRef) properties
    );
}

Вот то, как работает этот код:

  1. Получает путь файловой системы для нового основанного на файле индекса и преобразовывает его в объект NSString.

  2. Преобразовывает объект NSString в объект NSURL.

  3. Получает дополнительное имя индекса, если предоставленный, и сохраняет его в объекте NSString. Если нет никакого имени индекса, использования nil.

  4. Определяет индексный тип, в этом случае, указывающем инвертированный индекс.

  5. Указывает длину минимального срока как объект NSNumber.

  6. Указывает список стоп-слов как объект NSSet.

  7. Указывает словарь свойств анализа текста, включая длину минимального срока, стоп-слова и спецификации символа дополнительного условия.

  8. Создает новый, пустой, основанный на файле индекс с помощью указанного URL, имени, введите, и свойства анализа текста. Возвращает Поисковый индексный объект Набора.

Загрузка текстовых средств импорта центра внимания

Загрузка текстовых средств импорта Центра внимания является одноступенчатым процессом, который приложения обычно выполняют во время запуска.

Перечисление 3-8  , Загружающее текстовые средства импорта Центра внимания

- (void) loadImporters {
    SKLoadDefaultExtractorPlugIns ();
}

Добавление основанного на файле документа индексу

Для добавления основанного на файле документа индексу приложение просто предоставляет индексный объект и документ объект URL. Можно дополнительно обеспечить подсказку типа MIME, как описано в Ссылке SearchKit. Наконец, Вы указываете документ как заменимый или нет.

Перечисление 3-9  , Добавляющее основанный на файле документ индексу

- (void) addDoc {
    NSString *path = [myFilePathTextField stringValue];  // 1
    NSURL *url = [NSURL fileURLWithPath: path];          // 2
    SKDocumentRef doc = SKDocumentCreateWithURL (        // 3
                            (CFURLRef) url
                        );
 
    Boolean added = SKIndexAddDocument (                 // 5
        (SKIndexRef) mySKIndex,
        (SKDocumentRef) doc,
        (CFStringRef) NULL,    // optional MIME type hint
        (Boolean) true         // replaceable
    );
}

Как работает этот код:

  1. Заставляет путь файловой системы для документа быть добавленным к индексу. Преобразовывает строку пути в объект NSString.

  2. Преобразовывает объект NSString в объект NSURL.

  3. Создает документ объект URL из объекта NSURL.

  4. Добавляет документ, идентифицированный документом объект URL, вместе с его текстом, к указанному Поисковому индексу Набора.

Добавление папки основанных на файле документов индексу

Для индексации папки документов приложение использует другие платформы Какао. Эта задача иллюстрирует, как убывать рекурсивно в структуру папок.

Перечисление 3-10  , Добавляющее папку основанных на файле документов индексу

- (void) addDocsInFolder {
    NSString *path = [myFilePathTextField stringValue];    // 1
 
    NSDirectoryEnumerator *dirEnumerator =                 // 2
        [[NSFileManager defaultManager] enumeratorAtPath: path];
 
    NSString *item;
    while ((item = [dirEnumerator nextObject]) != nil) {   // 3
        NSString *fullPath =                               // 4
            [path stringByAppendingPathComponent: item];
        if (!fullPath) continue;
 
        NSURL *url =                                       // 5
            [NSURL fileURLWithPath: fullPath];
        if (!url) continue;
 
        SKDocumentRef doc = SKDocumentCreateWithURL (      // 6
                                (CFURLRef) url
                            );
        if (!doc) continue;
 
        Boolean added = SKIndexAddDocument (               // 8
            (SKIndexRef) mySKIndex,
            (SKDocumentRef) doc,
            (CFStringRef) NULL,   // optional MIME type hint
            (Boolean) true        // replaceable
        );
    }
}

Вот то, как работает этот код:

  1. Получает путь файловой системы для папки, содержащей основанные на файле документы. Преобразовывает строку пути в объект NSString.

  2. Создает объект NSDirectoryEnumerator для того, чтобы рекурсивно найти все основанные на файле документы в папке.

  3. Шаги через перечислитель, получая путь к каждому основанному на файле документу в папке.

  4. Преобразовывает каждый путь к объекту NSString.

  5. Преобразовывает каждый объект NSString в объект NSURL.

  6. Создает документ объект URL из каждого объекта NSURL.

  7. Добавляет документ, идентифицированный документом объект URL, вместе с его текстом, к указанному Поисковому индексу Набора.

Добавление текста явно к индексу

Для добавления текста явно к индексу приложение получает текст, анализирует его по мере необходимости, и затем передает его вместе с индексным объектом для Поиска Набора. Этот пример иллюстрирует текст индексации от текстового поля в пользовательском интерфейсе приложения. Вы могли точно также взять текст от записи базы данных или от удаленного URL, например.

Перечисление 3-11  , Добавляющее текст явно к индексу

- (void) addDocWithText {
    NSString *path = [myFilePathTextField stringValue];  // 1
    NSURL *url = [NSURL fileURLWithPath:path];           // 2
 
    SKDocumentRef doc = SKDocumentCreateWithURL (        // 3
                            (CFURLRef) url
                        );
 
    NSString *contents = [fileContentsTextView string];  // 5
    Boolean added = SKIndexAddDocumentWithText (         // 6
                        mySKIndex,
                        doc,
                        (CFStringRef) contents,
                        (Boolean) true     // replaceable
                    );
}

Вот то, как работает этот код:

  1. Заставляет путь файловой системы для документа быть добавленным к индексу. Преобразовывает строку пути в объект NSString.

  2. Преобразовывает объект NSString в объект NSURL.

  3. Создает документ объект URL из объекта NSURL.

  4. Получает текстовое содержание от текстового поля пользовательского интерфейса и преобразовывает его в объект NSString.

  5. Добавляет документ объект URL вместе с указанным текстом к указанному Поисковому индексу Набора. Текст связан в индексе с документом, которому URL возражает таким образом, который запрашивает то соответствие, условия в тексте возвратят документ объект URL.

Обновление индекса, когда изменяется документ

Чтобы повторно индексировать документ, изменившийся, просто замените его в индексе. Сделайте это путем вызова SKIndexAddDocumentWithText или SKIndexAddDocument функция, как надлежащий, с inCanReplace набором параметра к a true значение. Этот пример предполагает, что включенный документ является локальным, основанным на файле документом и так использует SKIndexAddDocument функция.

Перечисление 3-12  , Обновляющее индекс, когда изменяется документ

- (void) replaceChangedDoc: (id) sender {
    NSString *path = [myFilePathTextField stringValue];   // 1
    NSURL *url = [NSURL fileURLWithPath:path];
    SKDocumentRef doc = SKDocumentCreateWithURL (
                            (CFURLRef) url
                        );
 
    Boolean replaced = SKIndexAddDocument (               // 2
                        mySKIndex,
                        doc,
                        NULL,
                        true
                    );
}
  1. Получает путь файловой системы для заменяющего документа. Преобразовывает строку пути в объект NSString.]

  2. Заменяет документ, идентифицированный документом объект URL, вместе с его текстом, в указанном Поисковом индексе Набора.

Обновление индекса, когда документ перемещается или перемещается и изменяется

Чтобы повторно индексировать документ, переместившийся, или переместившийся и изменившийся, выполняют эти три шага:

  1. Удалите старый документ с SKIndexRemoveDocument функция.

  2. Удалите старый текст (при желании, или если индекс значительно фрагментируется) с SKIndexCompact функция.

  3. Добавьте измененный документ и его текст к индексу.

Уплотнение индекса во время этого процесса удаляет любые осиротевшие условия. Однако SKIndexCompact функция может быть дорогой с точки зрения производительности. Apple рекомендует не вызвать его каждый раз, когда документ изменен или удален, но только когда индекс значительно фрагментируется (чрезмерно увеличенный в размере с неиспользованным текстом).

Для проверки на чрезмерное увеличение размера, можно использовать в своих интересах способ, которым Набор Поиска выделяет документ IDs. Это делает настолько стартовый в 1, и не снова используя ранее выделил IDs для индекса. Просто сравните самый высокий документ ID, найденный с SKIndexGetMaximumDocumentID функция, с количеством текущего документа, найденным с SKIndexGetDocumentCount функция.

Следующий простой пример иллюстрирует уплотнение, не проверяя на индексное чрезмерное увеличение размера.

Перечисление 3-13  , Обновляющее индекс, когда документ перемещается или перемещается и изменяется

- (void) replaceDoc: (id) sender {
//..........................................................................
// remove a specified document from an index
    NSString *path = [myFilePathTextField stringValue]; // 1
    NSURL *url = [NSURL fileURLWithPath: path];         // 2
 
    SKDocumentRef doc = SKDocumentCreateWithURL (       // 3
                            (CFURLRef) url
                        );
 
    Boolean removed = SKIndexRemoveDocument (           // 5
                          mySKIndex,
                          doc
                       );
//..........................................................................
// compact the index to remove the terms associated with the removed document
    SKIndexCompact (mySKIndex);                         // 6
//..........................................................................
// add the document and its terms back to the index
    NSString *path = [myFilePathTextField stringValue]; // 7
    NSURL *url = [NSURL fileURLWithPath:path];
    SKDocumentRef doc = SKDocumentCreateWithURL (
                            (CFURLRef) url
                        );
 
    Boolean added = SKIndexAddDocument (                // 8
                        mySKIndex,
                        doc,
                        NULL,
                        true
                    );
}

Вот то, как работает этот код:

  1. Заставляет путь файловой системы для документа быть удаленным из индекса. Преобразовывает строку пути в объект NSString.

  2. Преобразовывает объект NSString в объект NSURL.

  3. Создает документ объект URL из объекта NSURL.

  4. Удаляет документ объект URL из указанного индекса.

  5. Уплотняет индекс для удаления условий, связанных с удаленным документом.

  6. Получает путь файловой системы для заменяющего документа. Преобразовывает строку пути в объект NSString.

  7. Добавляет заменяющий документ, идентифицированный документом объект URL, вместе с его текстом, к указанному Поисковому индексу Набора.

Поиск

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

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

Установка параметров поиска

Когда Ваше приложение создает поисковый объект, оно может указать множество параметров поиска. Каждая опция является просто двоичным флагом для inSearchOptions параметра SKSearchCreate функция.

Перечисление 3-14  , Настраивающее параметры поиска

SKSearchOptions options = kSKSearchOptionDefault;    // 1
 
if ([searchOptionNoRelevance intValue])              // 2
    options |= kSKSearchOptionNoRelevanceScores;
if ([searchOptionSpaceIsOR intValue])                // 3
    options |= kSKSearchOptionSpaceMeansOR;
if ([searchOptionSpaceFindSimilar intValue])         // 4
    options |= kSKSearchOptionFindSimilar;

Вот то, как работает этот код:

  1. Указывает использование набора по умолчанию параметров поиска.

  2. Если пользователь указал, что поиски не должны рассматривать уместность, добавляет та опция.

  3. Если пользователь указал, что пробелы должны указать логическое OR в запросе добавляет та опция.

  4. Если пользователь указал, что подобие, ищущее вместо основанного на запросе поиска, добавляет ту опцию.

Получение запроса пользователя

Эта задача иллюстрирует простой шаг создания объекта NSString от запроса пользователя.

Перечисление 3-15  , Получающее запрос пользователя

NSString *query = [mySearchField stringValue];

Создание асинхронного поискового объекта

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

Перечисление 3-16  , Создающее асинхронный поисковый объект

SKSearchRef search = SKSearchCreate (            // 1
                         mySKIndex,
                         (CFStringRef) query,
                         options
                     );

Этот код создает поиск, основанный на объектах на запросе пользователя и указанных параметрах поиска, предназначаясь для указанного Поискового индекса Набора.

Получение соответствий от поискового объекта

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

Результатом хита является легкий идентификатор документа. Следующая задача, Получение Расположений Документа и Отображение Результатов, иллюстрирует преобразование идентификаторов документа для документирования расположений, как представлено документом объекты URL.

Перечисление 3-17  , Получающее соответствия от поискового объекта

while (more) {
    SKDocumentID    foundDocIDs [kSearchMax];         // 1
    float           foundScores [kSearchMax];         // 2
    float *scores;                                    // 3
    Boolean unranked =                                // 4
        options & kSKSearchOptionNoRelevanceScores;
 
    if (unranked) {                                   // 5
        scores = NULL;
    } else {
        scores = foundScores;
    }
 
    CFIndex foundCount = 0;                           // 6
    more = SKSearchFindMatches (                      // 7
              search,
              kSearchMax,
              foundDocIDs,
              scores,
              1,    // maximum time before function returns, in seconds
              &foundCount
          );
    // display or accumulate results here
 
    totalCount += foundCount;                         // 8
}

Вот то, как работает этот код:

  1. Устанавливает массив для содержания идентификаторов документа, следующих из хитов во время поиска.

  2. Устанавливает массив для содержания очков уместности.

  3. Устанавливает указатель на массив очков уместности.

  4. Создает булев флаг, указывающий, нужно ли сообщить об очках уместности.

  5. Использует флаг уместности для определения outScoresArray параметра для SKSearchFindMatches функция.

  6. Инициализирует найденное количество к 0.

  7. Запрашивает поисковый объект. SKSearchFindMatches функционируйте хиты мест в массиве foundDocIDs, очки уместности в массиве очков и булево значение, указывающее, существует ли больше результатов, которые будут иметься (TRUE) или не (FALSE).

  8. Накапливает число новых соответствий в общее количество соответствий.

Получение расположений документа и отображение результатов

Для получения результатов, которые значимы для пользователя Вы преобразовываете каждый из идентификаторов документа, предоставленных поисковым объектом как хиты, к расположению документа в форме документа объект URL. Эта задача иллюстрирует простое журналирование результатов — включая документ ID, документ URL и счет уместности если применимо — к текстовому полю.

В этой выборке кода, и в полном примере, показанном в Полном Методе поиска, код просто выводит на экран результаты, поскольку они найдены. Используя другие платформы Какао, можно хотеть, вместо этого, накопить результаты и представить их в единственном списке, сортированном уместностью и возможно динамично обновленном.

Перечисление 3-18  , Получающее расположения документа и выводящее на экран результаты

SKDocumentRef   foundDocRefs [kSearchMax];                 // 1
SKIndexCopyDocumentRefsForDocumentIDs (                    // 2
    mySKIndex,
    (CFIndex) foundCount,
    foundDocIDs,
    foundDocRefs
);
 
CFIndex pos;
for (pos = 0; pos < foundCount; pos++) {                   // 3
    SKDocumentRef doc = (SKDocumentRef) foundDocRefs[pos]; // 4
 
    NSURL *url = SKDocumentCopyURL (doc);                  // 5
 
    NSString *urlStr = [url absoluteString];               // 6
 
    NSString *desc;
    if (unranked) {                                        // 7
        desc = [NSString stringWithFormat:
            @"---\nDocID: %d,
            URL: %@",
            (int) foundDocIDs [pos],
            urlStr];
    } else {
        desc = [NSString stringWithFormat:
            @"---\nDocID: %d,
            Score: %f,
            URL: %@",
            (int) foundDocIDs[ pos],
            foundScores [pos],
            urlStr];
    }
    [self log: desc];                                      // 8

Вот то, как работает этот код:

  1. Устанавливает массив для содержания документа объекты URL, полученные из идентификаторов документа, собранных в Получении Соответствий От Поискового Объекта.

  2. Преобразовывает идентификаторы документа для документирования объектов URL. Найденное количество и идентификаторы документа от Получения Соответствий От Поискового Объекта.

  3. Выполняет итерации через foundDocRefs выстройте для преобразования документа, которому URL возражает против объектов NSString для дисплея.

  4. Получает следующий документ объект URL.

  5. Для текущего документа объект URL, получает URL.

  6. Преобразовывает URL в объект NSString.

  7. Форматирует информацию о результате для текущего хита. Информация, которая будет выведена на экран, зависит от того, был ли поиск оценен или не оценен.

  8. Выводит на экран результаты, использующие приложения log: метод (не проиллюстрированный здесь).

Полный метод поиска

Эта задача собирает предыдущие выборки кода в этом разделе и представляет полную методику поиска. Как описано во введении в этот раздел, Ваше приложение:

  • Указывает максимальное количество хитов для возврата.

  • Устанавливает параметры поиска.

  • Получает запрос пользователя.

  • Создает асинхронный поисковый объект.

  • Запросы совершают нападки от поискового объекта.

  • Преобразовывает хиты в расположения документа и выводит на экран результаты.

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

Перечисление 3-19  полный метод поиска

//..........................................................................
// specify the maximum number of hits
#define kSearchMax 1000
 
- (void) search {
//..........................................................................
// set up search options
    SKSearchOptions options = kSKSearchOptionDefault;
 
    if ([searchOptionNoRelevance intValue]) options |= kSKSearchOptionNoRelevanceScores;
    if ([searchOptionSpaceIsOR intValue]) options |= kSKSearchOptionSpaceMeansOR;
    if ([searchOptionSpaceFindSimilar intValue]) options |= kSKSearchOptionFindSimilar;
 
//..........................................................................
// get the user's query
    NSString *query = [mySearchField stringValue];
 
//..........................................................................
// create an asynchronous search object
    SKSearchRef search = SKSearchCreate (
                             mySKIndex,
                             (CFStringRef) query,
                             options
                         );
 
//..........................................................................
// get matches from a search object
    Boolean more = true;
    UInt32 totalCount = 0;
 
    while (more) {
        SKDocumentID  foundDocIDs [kSearchMax];
        float         foundScores [kSearchMax];
        SKDocumentRef foundDocRefs [kSearchMax];
 
        float *scores;
        Boolean unranked = options & kSKSearchOptionNoRelevanceScores;
 
        if (unranked) {
            scores = NULL;
        } else {
            scores = foundScores;
        }
 
        CFIndex foundCount = 0;
        CFIndex pos;
 
        more =  SKSearchFindMatches (
                    search,
                    kSearchMax,
                    foundDocIDs,
                    scores,
                    1, // maximum time before func returns, in seconds
                    &foundCount
                );
 
        totalCount += foundCount;
 
//..........................................................................
// get document locations for matches and display results.
//     alternatively, you can collect results over iterations of this loop
//     for display later.
 
        SKIndexCopyDocumentRefsForDocumentIDs (
            (SKIndexRef) mySKIndex,
            (CFIndex) foundCount,
            (SKDocumentID *) foundDocIDs,
            (SKDocumentRef *) foundDocRefs
        );
 
        for (pos = 0; pos < foundCount; pos++) {
            SKDocumentRef doc = (SKDocumentRef) foundDocRefs[pos];
            NSURL *url = SKDocumentCopyURL (doc);
            NSString *urlStr = [url absoluteString];
 
            NSString *desc;
 
            if (unranked) {
                desc = [NSString stringWithFormat:
                        @"---\nDocID: %d, URL: %@",
                        (int) foundDocIDs[pos], urlStr];
            } else {
                desc = [NSString stringWithFormat:
                        @"---\nDocID: %d, Score: %f, URL: %@",
                        (int) foundDocIDs[pos], foundScores[pos], urlStr];
            }
            [self log: desc];
        }
    }
 
    NSString *desc = [NSString stringWithFormat:
                        @"\"%@\" - %d matches", query, (int) totalCount];
    [self log: desc];
}

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

Используя тайм-аут для поиска Index Group параллельно

Для поиска индексной группы параллельно, можно использовать отдельный поток для запросов каждого поискового объекта. Также, как проиллюстрировано здесь, можно неоднократно вращаться через ряд поисковых объектов, запрашивая один и затем идя дальше к следующему, при помощи опции тайм-аута в SKSearchFindMatches функция.

Перечисление 3-20  Используя тайм-аут для поиска индексной группы параллельно

completeCount = indexCount;                   // 1
while (completeCount) {                       // 2
    for (i = 0; i < indexCount; i++) {
        if (more [i]) {
            more [i] = SKSearchFindMatches (  // 3
                           searchObjects [i],
                           kSearchMax,
                           foundDocIDs,
                           scores,
                           timeout,
                           &foundCount
                       );
 
            if (!more [i]) completeCount--;   // 4
            ProcessHits (                     // 5
                searchObjects [i],
                foundDocIDs,
                scores,
                foundCount
            );
        }
    }
}

Вот то, как работает этот код:

  1. Инициализирует completeCount переменная к числу индексов в группе. Приложение с помощью этого кода ранее определило бы один поисковый объект на индекс в группе. Это также инициализировало бы more массив с true значения для каждого элемента. completeCount переменная содержит уменьшающееся число поисковых объектов, все еще имеющих результаты в наличии.

  2. Выполняет итерации через список поисковых объектов, получая хиты от каждого поочередно. После периода, указанного параметром тайм-аута, идет дальше к следующему поисковому объекту. Пока хиты по крайней мере из одного поискового объекта не исчерпываются, повторяет итерацию.

  3. Получает следующий набор поисковых хитов для текущего поискового объекта, накапливая результаты в foundDocIDs, scores, и foundCount.

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

  5. Вызывает определенный с помощью приложения ProcessHits функционируйте для работы с новыми поисковыми хитами.