<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.search.lucene.index-creation">
    <title>Construindo Índices</title>

    <sect2 id="zend.search.lucene.index-creation.creating">
        <title>Criando um Novo Índice</title>

        <para>
            As funcionalidades de criação e atualização de índices são implementadas tanto no
            componente <classname>Zend_Search_Lucene</classname> como no projeto Java Lucene. Você
            pode usar qualquer uma destas opções para criar índices pesquisáveis pelo
            <classname>Zend_Search_Lucene</classname>.
        </para>

        <para>
            O código <acronym>PHP</acronym> abaixo mostra um exemplo de como indexar um arquivo
            usando a <acronym>API</acronym> de indexação do
            <classname>Zend_Search_Lucene</classname>:
        </para>

        <programlisting language="php"><![CDATA[
// Cria o índice
$index = Zend_Search_Lucene::create('/data/my-index');

$doc = new Zend_Search_Lucene_Document();

// Armazena a URL do documento para identificá-lo nos resultados da pesquisa
$doc->addField(Zend_Search_Lucene_Field::Text('url', $docUrl));

// Indexa os conteúdos do documento
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', $docContent));

// Adiciona o documento ao índice
$index->addDocument($doc);
]]></programlisting>

        <para>
            Documentos adicionados recentemente são imediatamente pesquisáveis no índice.
        </para>
    </sect2>

    <sect2 id="zend.search.lucene.index-creation.updating">
        <title>Atualizando um Índice</title>

        <para>
            O mesmo procedimento é empregado para atualizar um índice existente. A única diferença
            é que o método open() é chamado no lugar do método create():
        </para>

        <programlisting language="php"><![CDATA[
// Abre um índice existente
$index = Zend_Search_Lucene::open('/data/my-index');

$doc = new Zend_Search_Lucene_Document();
// Armazena a URL do documento para identificá-lo no resultado da pesquisa
$doc->addField(Zend_Search_Lucene_Field::Text('url', $docUrl));
// Indexa o conteúdo do documento
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents',
                                                  $docContent));

// Adiciona o documento ao índice
$index->addDocument($doc);
]]></programlisting>
    </sect2>

    <sect2 id="zend.search.lucene.index-creation.document-updating">
        <title>Atualizando os Documentos</title>

        <para>
            O formato de arquivo do índice Lucene não suporta a atualização do documento. Os
            documentos devem ser removidos e adicionados novamente ao índice para atualizá-los de
            forma eficaz.
        </para>

        <para>
            O método <methodname>Zend_Search_Lucene::delete()</methodname> funciona com uma
            identificação interna do índice do documento. Ela pode ser recuperada de uma consulta
            pela propriedade 'id':
        </para>

        <programlisting language="php"><![CDATA[
$removePath = ...;
$hits = $index->find('path:' . $removePath);
foreach ($hits as $hit) {
    $index->delete($hit->id);
}
]]></programlisting>
    </sect2>

    <sect2 id="zend.search.lucene.index-creation.counting">
        <title>Recuperando o Tamanho do Índice</title>

        <para>
            Existem dois métodos para recuperar o tamanho de um índice no
            <classname>Zend_Search_Lucene</classname>.
        </para>

        <para>
            O método <methodname>Zend_Search_Lucene::maxDoc()</methodname> retorna um número maior
            do que o maior número possível de documentos. É na verdade o número total de documentos
            no índice incluindo os documentos excluídos, por isso ele tem um sinônimo:
            <methodname>Zend_Search_Lucene::count()</methodname>.
        </para>

        <para>
            O método <methodname>Zend_Search_Lucene::numDocs()</methodname> retorna o número total
            de documentos que não foram excluídos.
        </para>

        <programlisting language="php"><![CDATA[
$indexSize = $index->count();
$documents = $index->numDocs();
]]></programlisting>

        <para>
            O método <methodname>Zend_Search_Lucene::isDeleted($id)</methodname> pode ser usado para
            verificar se um documento foi excluído.
        </para>

        <programlisting language="php"><![CDATA[
for ($count = 0; $count < $index->maxDoc(); $count++) {
    if ($index->isDeleted($count)) {
        echo "O documento #$id foi excluído.\n";
    }
}
]]></programlisting>

        <para>
            A otimização do índice remove os documentos excluídos e comprime as IDs dos documentos
            em um intervalo menor. Assim, uma id interna de um documento pode ser alterada durante
            a otimização do índice.
        </para>
    </sect2>

    <sect2 id="zend.search.lucene.index-creation.optimization">
        <title>Otimização do Índice</title>

        <para>
            Um índice Lucene é composto por vários segmentos. Cada segmento é um conjunto de dados
            completamente independente.
        </para>

        <para>
            Os arquivos de segmento de índice Lucene não podem ser atualizados devido ao seu
            projeto. A atualização de um segmento necessita de uma reorganização completa do
            segmento. Veja os formatos de arquivos de índice Lucene para mais detalhes (<ulink
                url="http://lucene.apache.org/java/2_3_0/fileformats.html">http://lucene.apache.org/java/2_3_0/fileformats.html</ulink>)

            <footnote>
                <para>
                    O formato de arquivo de índice Lucene atualmente suportado é a versão 2.3
                    (desde Zend Framework 1.6).
                </para>
            </footnote>.

            Novos documentos são adicionados ao índice através da criação de um novo segmento.
        </para>

        <para>
            O aumento do número de segmentos reduz a qualidade do índice, mas uma otimização do
            índice resolverá o problema. Essencialmente, a otimização mescla vários segmentos em um
            novo. Além disso, este processo não atualiza os segmentos. Ele gera um novo grande
            segmento e atualiza a lista de segmentos (arquivo 'segments').
        </para>

        <para>
            A otimização completa do índice pode ser feita chamando o método
            <methodname>Zend_Search_Lucene::optimize()</methodname>. Ele funde todos os segmentos de
            índice em um novo segmento:
        </para>

        <programlisting language="php"><![CDATA[
// Abre um índice existente
$index = Zend_Search_Lucene::open('/data/my-index');

// Otimiza o índice
$index->optimize();
]]></programlisting>

        <para>
            A otimização automática do índice é realizada para manter os índices em um estado
            consistente.
        </para>

        <para>
            A otimização automática é um processo iterativo controlado por várias opções de índice.
            Ele funde segmentos muito pequenos para obter outros maiores, então mescla esses
            segmentos em segmentos ainda maiores e assim por diante.
        </para>

        <sect3 id="zend.search.lucene.index-creation.optimization.maxbuffereddocs">
            <title>Opção de auto-otimização MaxBufferedDocs</title>

            <para>
                <emphasis>MaxBufferedDocs</emphasis> é o número mínimo de documentos necessários
                antes que os documentos presentes na memória dentro do buffer sejam escritos em um
                novo segmento.
            </para>

            <para>
                <emphasis>MaxBufferedDocs</emphasis> pode ser recuperado ou definido pelas chamadas
                <code>$index->getMaxBufferedDocs()</code> ou
                <code>$index->setMaxBufferedDocs($maxBufferedDocs)</code>.
            </para>

            <para>
                O valor padrão é 10.
            </para>
        </sect3>

        <sect3 id="zend.search.lucene.index-creation.optimization.maxmergedocs">
            <title>Opção de auto-otimização MaxMergeDocs</title>

            <para>
                <emphasis>MaxMergeDocs</emphasis> é o maior número de documentos já fundidos por
                addDocument(). Valores pequenos (p. ex., menores que 10.000) são os melhores para
                indexação interativa, visto que isso limita em alguns segundos a duração das pausas
                durante a indexação. Os maiores valores são os melhores para a indexação em lote e
                buscas rápidas.
            </para>

            <para>
                <emphasis>MaxMergeDocs</emphasis> pode ser recuperado ou definido pelas chamadas
                <code>$index->getMaxMergeDocs()</code> ou
                <code>$index->setMaxMergeDocs($maxMergeDocs)</code>.
            </para>

            <para>
                O valor padrão é PHP_INT_MAX.
            </para>
        </sect3>

        <sect3 id="zend.search.lucene.index-creation.optimization.mergefactor">
            <title>Opção de auto-otimização MergeFactor</title>

            <para>
                <emphasis>MergeFactor</emphasis> determina a frequência com que os índices de
                segmento são fundidos por addDocument(). Com valores menores, menos memória
                <acronym>RAM</acronym> é usada durante a indexação, e buscas em índices não
                otimizados são mais rápidas, mas a velocidade de indexação é mais lenta. Com valores
                maiores, mais memória <acronym>RAM</acronym> é usada durante a indexação, e, embora
                as buscas em índices não otimizados sejam mais lentas, a indexação é mais rápida.
                Desse modo, valores maiores (&gt; 10) são melhores para a criação de índices em
                lotes, e os valores menores (&lt; 10) são melhores para os índices que são mantidos
                de forma interativa.
            </para>

            <para>
                <emphasis>MergeFactor</emphasis> é uma boa estimativa para o número médio de
                segmentos fundidos em uma passagem de auto-otimização. Valores muito grandes
                produzem um grande número de segmentos, enquanto não são fundidos em um novo. Isso
                pode causar a mensagem de erro "failed to open stream: Too many open files". Essa
                limitação é dependente do sistema.
            </para>

            <para>
                <emphasis>MergeFactor</emphasis> pode ser recuperado ou definido pelas chamadas
                <code>$index->getMergeFactor()</code> ou
                <code>$index->setMergeFactor($mergeFactor)</code>.
            </para>

            <para>
                O valor padrão é 10.
            </para>

            <para>
                Lucene Java e Luke (Lucene Index Toolbox - <ulink
                    url="http://www.getopt.org/luke/">http://www.getopt.org/luke/</ulink>) também
                podem ser usados para otimizar um índice. O último lançamento do Luke (v0.8) é
                baseado no Lucene v2.3 e é compatível com a atual implementação do componente
                <classname>Zend_Search_Lucene</classname> (Zend Framework 1.6). Versões anteriores
                das implementações do <classname>Zend_Search_Lucene</classname> necessitam de outras
                versões das ferramentas Java Lucene para serem compatíveis:

                <itemizedlist>
                    <listitem>
                        <para>
                            Zend Framework 1.5 - Java Lucene 2.1 (Luke tool v0.7.1 - <ulink
                                url="http://www.getopt.org/luke/luke-0.7.1/"/>)
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            Zend Framework 1.0 - Java Lucene 1.4 - 2.1 (Luke tool v0.6 - <ulink
                                url="http://www.getopt.org/luke/luke-0.6/"/>)
                        </para>
                    </listitem>
                </itemizedlist>
            </para>
        </sect3>
    </sect2>

    <sect2 id="zend.search.lucene.index-creation.permissions">
        <title>Permissões</title>

        <para>
            Por padrão, arquivos de índice estão disponíveis para leitura e escrita por todos.
        </para>

        <para>
            É possível substituir esse comportamento com o método
            <methodname>Zend_Search_Lucene_Storage_Directory_Filesystem::setDefaultFilePermissions()</methodname>:
        </para>

        <programlisting language="php"><![CDATA[
// Recupera as permissões padrões
$currentPermissions =
    Zend_Search_Lucene_Storage_Directory_Filesystem::getDefaultFilePermissions();

// Fornece permissões de leitura e escrita apenas para o usuário e grupo atuais
Zend_Search_Lucene_Storage_Directory_Filesystem::setDefaultFilePermissions(0660);
]]></programlisting>
    </sect2>

    <sect2 id="zend.search.lucene.index-creation.limitations">
        <title>Limitações</title>

        <sect3 id="zend.search.lucene.index-creation.limitations.index-size">
            <title>Tamanho do Índice</title>

            <para>
                O tamanho do índice é limitado em 2GB para plataformas 32-bit.
            </para>

            <para>
                Utilize plataformas 64-bit para índices maiores.
            </para>
        </sect3>

        <sect3 id="zend.search.lucene.index-creation.limitations.filesystems">
            <title>Sistemas de Arquivos Suportados</title>

            <para>
                <classname>Zend_Search_Lucene</classname> utiliza <methodname>flock()</methodname>
                para fornecer pesquisas simultâneas, atualização de índice e otimização.
            </para>

            <para>
                De acordo com a <ulink
                    url="http://www.php.net/manual/en/function.flock.php">documentação</ulink> do
                <acronym>PHP</acronym>, "<methodname>flock()</methodname> não funcionará em NFS ou
                em qualquer outro sistema de arquivos em rede.".
            </para>

            <para>
                Não utilize sistemas de arquivos em rede com o
                <classname>Zend_Search_Lucene</classname>.
            </para>
        </sect3>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
