Pesquisar

Artigo
· Jul. 21 3min de leitura

Speed up your full-text searches with %iFind indexes

Greetings dear community members!

Many of you will remember the NLP capabilities available in IRIS under the name iKnow, which were deprecated not long ago. But...is everything deprecated? NO! A small village resists deprecation: iFind indexes!

And you might be wondering, what are these magnificent indexes for? Well, it's very simple: they index the text in String and Stream columns and dramatically speed up querying.

What are %iFind indices?

These are a type of bitmap-based indexes that map each unique value in a column to a string of bits, indicating for each row whether a given value is available. You can find more details about these types of indexes in the official documentation .

We have two types of indexes in %iFind, the minimum and the basic, which extends the former.

%iFind.Index.Minimal

Supports SQL searches for words and phrases using wildcards, fuzzy searches, and regular expressions. It does not support co-occurrence or positional phrase searches, nor does it support highlighting results.

%iFind.Index.Basic

It supports all the features of the minimal index (SQL wildcard word and phrase searching) and adds support for co-occurrence, positional phrase searching, and result highlighting. This index's features are sufficient for most common full-text searches.

How to define a %iFind index?

It couldn't be simpler. I'll show you with a small example of a development I've implemented to read public tender information in Spain:

Class Inquisidor.Object.Licitacion Extends (%Persistent, %XML.Adaptor) [ DdlAllowed ]
{

Property IdLicitacion As %String(MAXLEN = 200);
Property Titulo As %String(MAXLEN = 2000);
...

Index IndexIdLicitation On IdLicitacion [ PrimaryKey ];
Index IndexTitulo On (Titulo) As %iFind.Index.Basic(INDEXOPTION = 0, LANGUAGE = "es");

As you can see, we have defined the Title property on which we want to perform searches that allow me to find certain tenders. An example of the titles we will have will be the following:

Maintenance and support service for the CIVITAS software application for managing individual health cards for the Regional Health Department of Castile and León.

To define the %iFind index we'll use the %iFind.Index.Basic(INDEXOPTION = 0, LANGUAGE = "es") configuration. In this case, it's a basic index. As you can see, we have several properties that allow us to define how we want our index to work. Let's take a look at the available properties:

  • IGNOREPUNCTUATION: Supports 2 values, 0 and 1. By default it will have the value 1 and will ignore punctuation marks in the text.
  • INDEXOPTION: Also available in 0 and 1. Allows you to specify whether the index will allow lemmatization or decomposition of texts. Due to its large size, it should only be enabled when necessary (value 1).
  • LANGUAGE: to define the dictionary to be used in searches, in our example, Spanish.
  • LOWER: with values 0 or 1. It will allow you to indicate whether the index will be case sensitive, by default it will have the value 0, ignoring it.
  • USERDICTIONARY: to use a user dictionary prior to indexing.

How to use the %iFind index in a query¿Cómo usar el índice %iFind en una consulta?

To use this type of index we must use the following notation:

SELECT * FROM Inquisidor_Object.Licitacion WHERE %ID %FIND search_index(IndexTitulo, ?)

Let's see the index in action. In my example, I have a table with 800,000 public tender records. Let's look at the plan with the traditional LIKE on our table:

Now let's look at the plan using the index:

As you can see, the relative cost between the normal search and the search with the %iFind index is astronomical: 1239110280 for the query without an index versus 8323422 for the indexed query, making it 150 times faster.

If you'd like to see more details about the types of searches that %iFind indexes allow, here 's the associated documentation.

I hope it is useful to you!

15 Comments
Discussão (15)5
Entre ou crie uma conta para continuar
Artigo
· Jul. 21 3min de leitura

Acelera tus búsquedas de textos con índices %iFind

¡Saludos estimados miembros de la comunidad!

Muchos recordaréis las capacidades NLP disponibles en IRIS con el nombre de iKnow y que fueron deprecadas hará no mucho tiempo. Pero...¿Deprecado todo? ¡NO! Una pequeña aldea resiste a la deprecación, ¡los índices iFind!

Y os preguntaréis, ¿para qué valen estos magníficos índices? Pues muy sencillo, sirven para indexar los textos presentes en las columnas de tipo String y Stream y acelerar dramáticamente la velocidad de consulta sobre las mismas.

¿Qué son los índices %iFind?

Son un tipo de índices basados en mapas de bits, estos índices mapean cada valor único de una columna en una cadena de bits, indicando para cada fila si se dispone de determinado valor. Podéis ver más detalles de estos tipos de índices en la documentación oficial.

Disponemos de 2 tipos de índices en %iFind, el mínimo y el básico, que extiende del anterior.

%iFind.Index.Minimal

Admite búsquedas SQL de palabras y frases con comodines, búsquedas difusas y expresiones regulares. No admite búsquedas por coocurrencia ni por frases posicionales, ni el resaltado de resultados.

%iFind.Index.Basic

Admite todas las funciones del índice mínimo (búsqueda SQL de palabras y frases con comodines) y añade compatibilidad con coocurrencia, búsquedas de frases posicionales y resaltado de resultados. Las funciones de este índice son suficientes para la mayoría de las búsquedas de texto completo habituales.

¿Cómo definir un índice %iFind?

¡No podría ser más sencillo, os lo mostraré con un pequeño ejemplo de un desarrollo que he implementado para leer la información de licitaciones públicas de España:

Class Inquisidor.Object.Licitacion Extends (%Persistent, %XML.Adaptor) [ DdlAllowed ]
{

Property IdLicitacion As %String(MAXLEN = 200);
Property Titulo As %String(MAXLEN = 2000);
...

Index IndexIdLicitation On IdLicitacion [ PrimaryKey ];
Index IndexTitulo On (Titulo) As %iFind.Index.Basic(INDEXOPTION = 0, LANGUAGE = "es");

Como veis tenemos definida la propiedad Título sobre la que queremos hacer búsquedas que me permitan encontrar determinadas licitaciones, un ejemplo de los títulos que vamos a tener será el siguiente:

Servicio de mantenimiento y soporte de la aplicación informática CIVITAS para la gestión de la tarjeta sanitaria individual de la Gerencia Regional de Salud de Castilla y León.

Para definir el índice %iFind utilizaremos la configuración %iFind.Index.Basic(INDEXOPTION = 0, LANGUAGE = "es"), en este caso es un índice básico. Como podéis ver tenemos una serie de propiedades que nos permiten definir cómo queremos que trabaje nuestro índice, veamos las propiedades disponibles:

  • IGNOREPUNCTUATION: admite 2 valores, 0 y 1. Por defecto tendrá el valor 1 e ignorará los signos de puntuación en el texto.
  • INDEXOPTION: también con valores 0 y 1. Permite especificar si el índice permitirá lematización o descomposición de los textos. Debido al gran tamaño que puede requerir sólo se deberá habilitar en caso necesario (valor 1).
  • LANGUAGE: para definir el diccionario que se va a emplear en las búsquedas, en nuestro ejemplo, español.
  • LOWER: con valores 0 ó 1. Permitirá indicar si el índice será sensible a mayúsculas y minúsculas, por defecto tendrá el valor 0, ignorándolo.
  • USERDICTIONARY: para que el índice haga uso de un diccionario del usuario previamente a la indexación.

¿Cómo usar el índice %iFind en una consulta?

Para hacer uso de este tipo de índices deberemos usar la siguiente notación:

SELECT * FROM Inquisidor_Object.Licitacion WHERE %ID %FIND search_index(IndexTitulo, ?)

Veamos el índice en acción. En mi ejemplo tengo una tabla con 800.000 registros de licitaciones públicas. Veamos el plan con el tradicional LIKE sobre nuestra tabla:

Ahora veamos el plan usando el índice:

Como podéis ver el coste relativo entre la búsqueda normal y la búsqueda con el índice %iFind es astronómico: 1239110280 para la consulta sin índice por 8323422 para la consulta indexada, siendo 150 veces más rápida.

Si queréis ver en más detalle el tipo de búsquedas que permiten los índices %iFind aquí tenéis la documentación asociada.

¡Espero que os sea de utilidad!

1 Comment
Discussão (1)1
Entre ou crie uma conta para continuar
Pergunta
· Jul. 21

Activate a mirror database gives "protected" error

Hi,

I have a mirrored database called ROUTER.

I have a primary server T1 and a "Disaster Recovery" server T2.

When I activate ROUTER database on T2, I get the error it says the "Database could not be mounted".

I went to the audit database and it shows "Attempt to access a protected database".

T2 in mirror monintor shows "Connected" "Caught up" "Warning! Some databases need attention"

T2 show the ROUTER database as being "Mounted/R"

Both T1 & T2 are Linux servers. The ROUTER database file IRIS.DAT have the same Linux permissions

All productions on T1/T2 are not running.

What causes the error "Attempt to access a protected database"?

3 Comments
Discussão (3)3
Entre ou crie uma conta para continuar
Pergunta
· Jul. 20

Login error

Hi Guys, 

I've my users set in Security->Users in SMP, but I get the below error when trying to long in my application, any clues what this error means?  

"0 "_$lb($lb(864,,,,,,,,,$lb(,"US-SERENITY",$lb("e^UsersCSPLogin+87^%SYS.SECURITY^1","e^CSPLogin+103^%SYS.cspServer^1","e^CSPDispatch+909^%SYS.cspServer^1","d^CSPDispatch+907^%SYS.cspServer^1","d^ProcessRequest+1^%CSP.Session.1^1","d^Request+692^%SYS.cspServer2^1","d^Request+25^%SYS.cspServer2^1","d^ProcessRequest+1^%CSP.Request.1^1","d^css+15^%SYS.cspServer2^1","d^Server+64^%SYS.SERVER^2","d^^^0"))))

BTW my login page extends  %CSP.Login

Thanks

4 Comments
Discussão (4)3
Entre ou crie uma conta para continuar