2009-12-10 3 views
3

Chaque document de mon index Lucene est un peu similaire à un post dans stackoverflow et j'essaie de faire une recherche dans l'index (qui contient des millions de documents). Chaque utilisateur ne devrait pouvoir effectuer une recherche que par le biais des publications de l'entreprise. Je n'ai aucun contrôle sur la façon dont les données sont indexées et je n'ai besoin que de mettre en œuvre une simple recherche (qui fonctionne).Meilleures pratiques pour implémenter une recherche Lucene en Java

Voici mon premier projet:

String q = "mysql" 
String companyId = "1001" 

String[] fields = { "body", "subject", "number", "category", "tags"}; 

Float float10 = new Float(10); 
Float float5 = new Float(5); 

Map<String, Float> boost = new HashMap<String, Float>(); 
boost.put("body", float10); 
boost.put("subject", float10); 
boost.put("number", float5); 
boost.put("category", float5); 
boost.put("tags", float5);; 

MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, new StandardAnalyzer(), boost); 
mfqp.setAllowLeadingWildcard(true); 
Query userQuery = mfqp.parse(q); 

TermQuery companyQuery = new TermQuery(new Term("company_id", companyId)); 

BooleanQuery booleanQuery = new BooleanQuery(); 
BooleanQuery.setMaxClauseCount(50000) 
booleanQuery.add(userQuery, BooleanClause.Occur.MUST); 
booleanQuery.add(companyQuery, BooleanClause.Occur.MUST); 

FSDirectory directory = FSDirectory.getDirectory(new File("/tmp/index")); 
IndexSearcher searcher = SearcherManager.getIndexSearcherInstance(directory); 
Hits hits = searcher.search(booleanQuery); 

Son travail essentiellement fonctionnel, mais je vois des problèmes de mémoire. Je reçois une erreur Out of Memory tous les 4, 5 jours et j'ai pris un tas et j'ai vu que les objets Lucene Term et TermInfo étaient en tête de liste. J'utilise l'instance singlet de IndexSearcher et je ne peux voir qu'une seule occurrence dans le tas.

Des commentaires sur ce que je fais? Ce que je fais mal et ce que je peux faire mieux en général?

+0

La configuration est ok, mais la question est désespérément vague. Voulez-vous dire qu'il y a une fuite de mémoire? Comment le sais-tu? Quelle est votre preuve? –

+0

Modifié. J'espère que c'est plus clair maintenant. – Langali

+0

Avez-vous utilisé http://www.eclipse.org/mat/ pour faire l'analyse? – akuhn

Répondre

1

Il n'y a pas de bogue évident dans votre code (du moins pas pour autant que je sache). Il pourrait être préférable d'analyser votre tas avec un outil plus puissant que visualvm. Je recommande d'utiliser le Memory Analyzer (MAT) d'eclipse (non installé par défaut, mais disponible sur le site de mise à jour par défaut). C'est génial.

Si vous avez besoin d'aide pour utiliser MAT, veuillez vous référer à cet article de blog "Eclipse Memory Analyzer, 10 useful tips/articles" de Markus Kohler. Il est l'auteur de l'outil.

0

Où rencontrez-vous habituellement des problèmes de mémoire? Est-ce autour de ce bloc?

MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, new StandardAnalyzer(), boost); 
mfqp.setAllowLeadingWildcard(true); 
Query userQuery = mfqp.parse(q); 

Également, exécutez-vous le code pour l'interrogation en conjonction avec le processus d'indexation?

+0

L'indexeur et le moteur de recherche fonctionnent sur deux systèmes différents. Je pense que cela a à voir avec le nombre de colonnes que j'ai dans l'index, et le nombre de documents, ce qui provoque un énorme nombre de termes pour chaque recherche de champs multiples. – Langali

1

Quelle est la taille de votre tas? Y a-t-il des recherches qui provoquent une augmentation de votre utilisation de la mémoire? J'imagine que vous allez sur OOME lorsque vous effectuez des requêtes génériques. En interne, Lucene étend une requête générique à une requête OU de TOUS les termes qui correspondent au caractère générique. Ce problème est exacerbé par le fait que vous autorisez les caractères génériques de premier plan. Lancer une recherche comme "body: *" chargerait tous les termes du corps dans la mémoire. Ma recommandation serait d'exécuter un profileur de mémoire lors de l'exécution de requêtes génériques et de voir ce que vous obtenez. Si les requêtes génériques sont le coupable, désactivez au moins les caractères génériques principaux ou réduisez la limite de la clause de requête.

Questions connexes