You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@lucene.apache.org by Mossaab Bagdouri <ba...@yahoo.fr> on 2012/08/27 19:37:08 UTC

How to properly refresh MultiReader IndexSearcher in Lucene 4.0-BETA

Hi,

The context is that I've migrated from Lucene 3.6 to Lucene 4.0-BETA.
Lucene 3.6 had the convenient method IndexSearcher.isCurrent() for any
underlying IndexReader, including MultiReader. This is no more the case for
Lucene 4.0-BETA. I've been suffering in the last 48h until I came up with
this solution. I just want to share, and get feedbacks if any. The idea is
to create a new instance of MultiReader, add the old current SubReaders and
the new changed ones, refresh the IndexSearcher, then close the old
out-of-date SubReaders.

private IndexSearcher getIndexSearcher() {
        try {
            if (is == null || is.getIndexReader().getRefCount() == 0) {
                DirectoryReader newReaders[] = new DirectoryReader[2];
                for (int i = 0; i < 2; i++) {
                    newReaders[i] =
DirectoryReader.open(MyFSDirectories.get(i));
                }
                is = new IndexSearcher(new MultiReader(newReaders));
            } else {
                MultiReader mr = (MultiReader) is.getIndexReader();
                List<DirectoryReader> oldReaders = (List<DirectoryReader>)
mr.getSequentialSubReaders();
                DirectoryReader newReaders[] = new
DirectoryReader[oldReaders.size()];
                Set<Integer> toClose = new HashSet<>();
                for (int i = 0; i < oldReaders.size(); i++) {
                    DirectoryReader oldDirectoryReader = oldReaders.get(i);
                    if (oldDirectoryReader.isCurrent()) {
                        newReaders[i] = oldDirectoryReader;
                    } else {
                        toClose.add(i);
                        newReaders[i] =
DirectoryReader.openIfChanged(oldReaders.get(i));
                    }
                }

                is = new IndexSearcher(new MultiReader(newReaders));

                for (int i : toClose) {
                    oldReaders.get(i).close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return is;
    }

Regards,
Mossaab

RE: How to properly refresh MultiReader IndexSearcher in Lucene 4.0-BETA

Posted by Uwe Schindler <uw...@thetaphi.de>.
Hi,

your code unfortunatley will no longer work in later Lucene 4.0 releases.

In general the simpliest and "correct" way to do this is:
- Manage your DirectoryReaders completely separate from each other in something like a pool of subindex readers (e.g. use some too like SearcherManager to keep the alive, this is much easier than doing it yourself). Once you need to reopen one, just reopen it and save it.
- On *every* search create a new MultiReader() [this costs nothing, as it is just a wrapper] and wrap it with a new IndexSearcher [this also costs you nothing, as it is also just a wrapper].

Uwe

-----
Uwe Schindler
H.-H.-Meier-Allee 63, D-28213 Bremen
http://www.thetaphi.de
eMail: uwe@thetaphi.de


> -----Original Message-----
> From: Mossaab Bagdouri [mailto:bagdouri_mossaab@yahoo.fr]
> Sent: Monday, August 27, 2012 7:37 PM
> To: java-user@lucene.apache.org
> Subject: How to properly refresh MultiReader IndexSearcher in Lucene 4.0-
> BETA
> 
> Hi,
> 
> The context is that I've migrated from Lucene 3.6 to Lucene 4.0-BETA.
> Lucene 3.6 had the convenient method IndexSearcher.isCurrent() for any
> underlying IndexReader, including MultiReader. This is no more the case for
> Lucene 4.0-BETA. I've been suffering in the last 48h until I came up with this
> solution. I just want to share, and get feedbacks if any. The idea is to create a
> new instance of MultiReader, add the old current SubReaders and the new
> changed ones, refresh the IndexSearcher, then close the old out-of-date
> SubReaders.
> 
> private IndexSearcher getIndexSearcher() {
>         try {
>             if (is == null || is.getIndexReader().getRefCount() == 0) {
>                 DirectoryReader newReaders[] = new DirectoryReader[2];
>                 for (int i = 0; i < 2; i++) {
>                     newReaders[i] =
> DirectoryReader.open(MyFSDirectories.get(i));
>                 }
>                 is = new IndexSearcher(new MultiReader(newReaders));
>             } else {
>                 MultiReader mr = (MultiReader) is.getIndexReader();
>                 List<DirectoryReader> oldReaders = (List<DirectoryReader>)
> mr.getSequentialSubReaders();
>                 DirectoryReader newReaders[] = new
> DirectoryReader[oldReaders.size()];
>                 Set<Integer> toClose = new HashSet<>();
>                 for (int i = 0; i < oldReaders.size(); i++) {
>                     DirectoryReader oldDirectoryReader = oldReaders.get(i);
>                     if (oldDirectoryReader.isCurrent()) {
>                         newReaders[i] = oldDirectoryReader;
>                     } else {
>                         toClose.add(i);
>                         newReaders[i] =
> DirectoryReader.openIfChanged(oldReaders.get(i));
>                     }
>                 }
> 
>                 is = new IndexSearcher(new MultiReader(newReaders));
> 
>                 for (int i : toClose) {
>                     oldReaders.get(i).close();
>                 }
>             }
>         } catch (Exception e) {
>             e.printStackTrace();
>         }
>         return is;
>     }
> 
> Regards,
> Mossaab


---------------------------------------------------------------------
To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-user-help@lucene.apache.org