Usando um Índice Composto

O HashIndex composto aprimora o desempenho da consulta e evita a custosa varredura de mapa. O recurso também fornece uma maneira conveniente para a API HashIndex localizar objetos em cache quando os critérios de busca envolvem muitos atributos.

Desempenho Melhorado

Um HashIndex composto fornecer uma maneira rápida e conveniente de buscar objetos em cache com múltiplos atributos em critérios de busca de correspondência. O índice composto suporta todas as buscas de correspondência de atributo, mas não suportam buscas de intervalo.

Nota: Índices compostos não suportam o operador BETWEEN no idioma de consulta do ObjectGrid porque BETWEEN necessitaria de suporte de intervalo. Os condicionais maior que (>) e menor que (<) também não funcionam porque necessitam de índices de intervalo.

Um índice composto pode melhorar o desempenho de consultas se o índice composto apropriado estiver disponível para a condição WHERE. Isso significa que o índice composto tem exatamente os mesmos atributos envolvidos na condição WHERE com atributos integrais correspondidos.

Uma consulta pode ter muitos atributos envolvidos em uma condição como no exemplo a seguir.

SELECT a FROM Address a WHERE a.city='Rochester' AND a.state='MN' AND a.zipcode='55901'

O índice composto pode melhorar o desempenho da consulta evitando a varredura de mapa ou unindo vários resultados de índice de atributo único. No exemplo, se o índice composto for definido com atributos (city,state,zipcode), o mecanismo de consulta poderá utilizar o índice composto para localizar a entrada com city='Rochester', state='MN' e zipcode='55901'. Sem índice composto e índice de atributo nos atributos cidade, estado e código postal, o mecanismo de consulta terá de varrer o mapa ou juntar-se a múltiplas buscas de atributo único, o que geralmente tem gasto adicional caro. Também, a consulta de índice composto somente suporta um padrão integralmente correspondido.

Configurando um Índice Composto

É possível configurar a indexação composta de três maneiras: usando XML, programaticamente, e com anotações de entidade apenas para mapas de entidade.

Configuração Programática

O código de exemplo programático abaixo criará o mesmo índice composto do XML precedente.

	  HashIndex mapIndex = new HashIndex();
    mapIndex.setName("Address.CityStateZip");
    mapIndex.setAttributeName(("city,state,zipcode"));
    mapIndex.setRangeIndex(true);

    BackingMap bm = objectGrid.defineMap("mymap");
    bm.addMapIndexPlugin(mapIndex);

Observe que a configuração de um índice composto é a mesma que a configuração de um índice regular com XML, exceto para o valor da propriedade attributeName. No caso de um índice composto, o valor de attributeName é uma lista de atributos delimitados por vírgulas. Por exemplo, a classe de valor Endereço tem 3 atributos: cidade, estado e código postal. Um índice composto pode ser definido com o valor da propriedade attributeName como "city,state,zipcode" indicando a cidade, estado e código postal são incluídos no índice composto.

Também, note que o HashIndexes composto não suporta consultas de intervalo e, portanto, não pode ter a propriedade RangeIndex configurada para true.

Utilizando XML

Para configurar um índice composto com XML, inclua código como o abaixo no elemento backingMapPluginCollections do arquivo de configuração.

Composite index - XML configuration approach
<bean id="MapIndexPlugin" className="com.ibm.websphere.objectgrid.plugins.index.HashIndex" >
<property name="Name" type="java.lang.String" value="Address.CityStateZip"/>
<property name="AttributeName" type="java.lang.String" value="city,state,zipcode"/>
</bean>

Com anotações de entidade

No caso do mapa de entidade, a abordagem de anotação pode ser utilizada para definir um índice composto. É possível definir uma lista de CompositeIndex sem a anotaçãoCompositeIndexes no nível da classe de entidade. O CompositeIndex possui uma propriedade name e attributeNames. Cada CompositeIndex é associado com uma instância HashIndex aplicada à BackingMap associada da entidade. O HashIndex é configurado como um índice de não-intervalo.

@Entity
@CompositeIndexes({
    @CompositeIndex(name=" CityStateZip ", attributeNames=" city,state,zipcode"), 
    @CompositeIndex(name="lastnameBirthday", attributeNames=" lastname,birthday ")
 })
public class Address {
    @Id int id;
    String street;
    String city;
    String state;
    String zipcode;
    String lastname;
    Date birthday;
}

A propriedade nomeada para cada índice composto deve ser única dentro da entidade e do BackingMap. Se o nome não for especificado, um nome gerado será utilizado. A propriedade attributeNames é utilizada para preencher o HashIndex attributeName com a lista de atributos delimitados por vírgulas. Os nomes de atributos coincidem com os nomes de campo persistente quando as entidades são configuradas para usar acesso à campo, ou o nome da propriedade como definida para as convenções de nomenclatura JavaBeans para entidades de acesso à propriedade. Por exemplo: Se o nome do atributo for "street", o método getter da propriedade é denominado getStreet.

Executando Consultas de Índice Composto

Após um índice composto ser configurado, um aplicativo pode utilizar o método findAll(Object) da interface MapIndex para executar consultas, conforme abaixo.

Session sess = objectgrid.getSession();
ObjectMap map = sess.getMap("MAP_NAME");
MapIndex codeIndex = (MapIndex) map.getIndex("INDEX_NAME");
Object[] compositeValue = new Object[]{ MapIndex.EMPTY_VALUE,
			"MN", "55901"};
Iterator iter = mapIndex.findAll(compositeValue);
// Close the session (optional in Version 7.1.1 and later) 
for improved performance
sess.close();

O MapIndex.EMPTY_VALUE é designado para o compositeValue[ 0 ] que indica que o atributo cidade é excluído da avaliação. Somente objetos com atributo estado igual a "MN" e atributo código postal igual a "55901" serão incluídos no resultado.

As seguintes consultas se beneficiam da configuração do índice composto anterior:

SELECT a FROM Address a WHERE a.city='Rochester' AND a.state='MN' AND a.zipcode='55901'

SELECT a FROM Address a WHERE a.state='MN' AND a.zipcode='55901'

O mecanismo de consulta localizará o índice composto apropriado e o usará para melhorar o desempenho da consulta em casos de correspondência de atributo integral.

Em alguns cenários, o aplicativo pode precisar definir múltiplos índices compostos com atributos sobrepostos para satisfazer todas as consultas com atributos integrais correspondidos. Uma desvantagem de aumentar o número de índices é o possível gasto adicional de desempenho em operações de mapa.

Migração e Interoperabilidade

A única restrição para o uso de um índice composto é que um aplicativo não pode configurá-lo em um ambiente distribuído com contêineres heterogêneos. Contêineres antigos e novos não podem ser combinados, já que contêineres antigos não reconhecerão uma configuração de índice composto. O índice composto é exatamente igual ao índice de atributo regular existente, exceto que o anterior permite a indexação sobre vários atributos. Ao utilizar apenas o índice de atributo regular, um ambiente de contêineres combinados ainda é viável.