2017-09-26 3 views
0

J'essaie d'indexer des données géospatiales sur un indice Lucene qui a créé une région Geode, et exécuter des requêtes sur ces données avec Lucene's LatLonPoint méthodes d'interrogation de classe (comme newDistanceQuery ou newPolygonQuery méthodes). Exécution de l'application retourne une fois des résultats corrects, mais quand je lance le code pour la deuxième fois que je reçois l'exception suivante:Apache Lucene LatLonPoint Requête sur Geode

org.apache.lucene.index.IndexNotFoundException: 
no segments* file found in [email protected] lockFactory= 
[email protected]: files: [] 

Voici les classes:

Server.java

public class Server { 
final static Logger _logger = LoggerFactory.getLogger(Server.class); 

public static void main(String[] args) throws InterruptedException { 
    startServer(); 
} 

/** Start a Geode Cache Server with a locator */ 
public static void startServer() throws InterruptedException { 
    ServerLauncher serverLauncher = new ServerLauncher.Builder() 
      .setMemberName("server1") 
      .setServerPort(40404) 
      .set("start-locator", "127.0.0.1[10334]") 
      .set("jmx-manager", "true") 
      .set("jmx-manager-start", "true") 
      .build(); 

    ServerLauncher.ServerState state = serverLauncher.start(); 
    _logger.info(state.toString()); 

    Cache cache = new CacheFactory().create(); 
    createLuceneIndex(cache); 
    cache.createRegionFactory(RegionShortcut.PARTITION).create("locationsRegion"); 
} 

/** Create a Lucene Index with given cache */ 
public static void createLuceneIndex(Cache cache) throws InterruptedException { 
    LuceneService luceneService = LuceneServiceProvider.get(cache); 
    luceneService.createIndexFactory() 
      .addField("NAME") 
      .addField("LOCATION") 
      .addField("COORDINATES") 
      .create("locationsIndex", "locationsRegion"); 
} 
} 

Client. java

public class Client { 
private static ClientCache cache; 
private static Region<Integer, Document> region; 

public static void main(String[] args) throws LuceneQueryException, InterruptedException, IOException { 
    init(); 
    indexFiles(); 
    search(); 
} 

/** Initialize the client cache and region */ 
private static void init() { 
    cache = new ClientCacheFactory() 
      .addPoolLocator("localhost", 10334) 
      .create(); 

    if (cache != null) { 
     region = cache.<Integer, Document>createClientRegionFactory(
       ClientRegionShortcut.CACHING_PROXY).create("locationsRegion"); 
    } else { 
     throw new NullPointerException("Client cache is null"); 
    } 
} 

/** Add documents to the Lucene index */ 
private static void indexFiles() { 
    // Dummy data 
    List<Document> locations = Arrays.asList(
      DocumentBuilder.newSampleDocument("Exastax", 40.984929, 29.133506), 
      DocumentBuilder.newSampleDocument("Galata Tower", 41.025826, 28.974378), 
      DocumentBuilder.newSampleDocument("St. Peter and St. Paul Church", 41.024757, 28.972950)); 

    // Standart IndexWriter initialization. 
    Analyzer analyzer = new StandardAnalyzer(); 
    // Create a directory from geode region 
    Directory directory = RawLucene.returnRegionDirectory(cache, region, "locationsIndex"); 
    IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); 
    IndexWriter indexWriter; 
    try { 
     indexWriter = new IndexWriter(directory, indexWriterConfig); 
     indexWriter.addDocuments(locations); 
     indexWriter.commit(); 
     indexWriter.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

/** Search in the Lucene index */ 
private static void search() { 
    try { 
     DirectoryReader reader = DirectoryReader.open(RawLucene.returnRegionDirectory(cache, region, "locationsIndex")); 
     IndexSearcher indexSearcher = new IndexSearcher(reader); 

     Query query = LatLonPoint.newDistanceQuery("COORDINATES", 41.024873, 28.974346, 500); 
     ScoreDoc[] scoreDocs = indexSearcher.search(query, 10).scoreDocs; 
     for (int i = 0; i < scoreDocs.length; i++) { 
      Document doc = indexSearcher.doc(scoreDocs[i].doc); 
      System.out.println(doc.get("NAME") + " --- " + doc.get("LOCATION")); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
} 

RawLucene.java

public class RawLucene { 
public static Directory returnRegionDirectory(ClientCache cache, Region region, String indexName) { 
    return new RegionDirectory(region,new FileSystemStats(cache.getDistributedSystem(), indexName)); 
} 
} 

DocumentBuilder.java

public class DocumentBuilder { 
public static Document newSampleDocument(String name, Double lat, Double lon) { 
    Document document = new Document(); 
    document.add(new StoredField("NAME", name)); 
    document.add(new StoredField("LOCATION", lat + " " + lon)); 
    document.add(new LatLonPoint("COORDINATES", lat, lon)); 
    return document; 
} 
} 

Voici comment je commence l'application:

  1. Exécutez la classe Server
  2. Exécutez la classe Client avec les trois méthodes (l'exécution initiale. Fonctionne correctement et renvoie des résultats corrects)
  3. Exécutez la classe Client sans appeler la méthode indexFiles. (Deuxième exécution C'est ici que j'obtiens l'exception)

Pourquoi le code s'exécute correctement pour la première fois et déclenche une exception lors de la deuxième exécution?

Répondre

1

Il semble que vous utilisiez un mélange d'API publique de géode avec la classe interne RegionDirectory. L'API publique prend uniquement en charge l'ajout de documents en ajoutant des objets directement à une région et en interrogeant à l'aide de LuceneService.createQueryFactory(). Le module geode-lucene utilise RegionDirectory en interne, mais il l'utilise un peu différemment de celui que vous avez utilisé. Au lieu d'encapsuler une région entière du côté client, il encapsule des compartiments individuels côté serveur.

Je pense que ce qui se passe ici est que RegionDirectory et la classe FileSystem sous-jacente utilisent des API de géodes qui se comportent différemment lorsque vous les appelez sur le client. En particulier, je pense que lorsque la classe FileSystem recherche des fichiers, elle utilise Region.keySet qui, avec votre client de mise en cache, va retourner la liste des fichiers mis en cache du côté client. Je pense que cela explique pourquoi vous obtenez l'erreur sur aucun fichier.

Dommage que RegionDirectory ne soit pas une API publique et ne supporte pas vraiment la façon dont vous essayez de l'utiliser, car cela ressemble à un bon cas d'utilisation.