2010-04-14 4 views
1

Je dois exécuter une requête JOIN sur un index solr. J'ai deux xmls que j'ai indexés, person.xml et subject.xml.solr JOIN requête

Personne:

<doc> 
<field name="id">P39126</field> 
<field name="family">Smith</field> 
<field name="given">John</field> 
<field name="subject">S1276</field> 
<field name="subject">S1312</field> 
</doc> 

Objet:

<doc> 
<field name="id">S1276</field> 
<field name="topic">Abnormalities, Human</field> 
</doc> 

je dois afficher uniquement les informations de la personne doc, mais chaque requête doit correspondre à des champs à la fois personne et sujet. Dans le cas où la requête correspond uniquement au document sujet, j'ai besoin d'afficher tous les documents de la personne qui ont un identifiant correspondant. Est-ce possible de faire sans exécuter deux requêtes séparées? Quelque chose comme une requête JOIN ferait l'affaire.

Une aide?

Répondre

3

Je ne pense pas qu'il soit possible de faire ce que vous demandez avec une seule requête en utilisant votre schéma. Une chose que vous devez garder à l'esprit est de toujours considérer les index Solr comme des tables uniques dénormalisées. C'est parfois un défi et il peut arriver que vous deviez utiliser des index différents pour chaque type de données.

Pour votre problème, peut-être avoir un schéma comme celui-ci pourrait aider:

<doc> 
<field name="id">P39126</field> 
<field name="family">Smith</field> 
<field name="given">John</field> 
<field name="topic">Abnormalities, Human</field> <!-- subject S1276 --> 
<field name="topic">some, other, topics</field> <!-- subject S1312 --> 
</doc> 

Exécution d'une requête pour certains sujets avec ce schéma renverrait tout personne ayant ces sujets.

Quelques liens qui pourraient vous intéresser:

+0

Merci beaucoup Pascal. Je ne sais pas vraiment comment changer le schéma. Nous avons des fichiers XML assez gros pour indexer (environ 4) chacun avec son propre schéma ayant des ID qui se connectent les uns aux autres. Faire tous ces un grand xml signifie beaucoup de répétition et un énorme fichier xml. Je ne sais pas ce qui est mieux, en termes de performances. Faire quelques requêtes supplémentaires ou avoir un énorme xml avec beaucoup de répétition. – Sfairas

+1

J'aurais tendance à dire que, dans la plupart des cas, vous ne devriez pas vous inquiéter des répétitions et vous efforcez d'avoir votre entité principale complètement dénormalisée. L'indice Lucene est assez bon pour ça.Au moment de la requête, vous pouvez toujours utiliser le paramètre fl pour limiter ce qui va être retourné aux utilisateurs. –

0

Si vous ne pouvez pas dénormaliser comme suggéré par Pascal, vous pouvez écrire votre propre gestionnaire de requêtes pour faire la jointure : commencez par émettre une requête sur les rubriques demandées qui demandent le champ id de documents correspondants, puis émettez une requête BooleanQuery contenant une clause pour chaque identifiant (une TermQuery sur subject = id). Cela aura des performances assez médiocres s'il y a un grand nombre d'identifiants, mais cela devrait être bon s'il n'y a que quelques identifiants correspondants.

Si vous pensez que vos requêtes de "jointure" correspondront généralement à beaucoup (disons des centaines) de sujets, alors vous feriez probablement mieux de dénormaliser comme suggéré.

Je ne connais pas la façon la plus élégante d'émettre une requête à partir d'un gestionnaire, mais FWIW voici comment je le fais.

Map args = new HashMap(); 
// add your query parameters to the map, like fields to return 
args.put("fl", new String[]{"id"}); 
final SolrIndexSearcher searcher = req.getSearcher(); 
String query = "your query" 
LocalSolrQueryRequest newReq = new LocalSolrQueryRequest(core, query, "", 0, 0, args) { 
    @Override public SolrIndexSearcher getSearcher() { return searcher; } 
    @Override public void close() { } 
}; 
SolrQueryResponse newRsp = new SolrQueryResponse(); 
core.execute(core.getRequestHandler(newReq.getParams().get(CommonParams.QT)), newReq, newRsp); 
// query results will be in newRsp 
+0

Merci beaucoup! Dans mon cas, je pense que ce n'est pas vraiment une option. Mon ensemble de données est énorme et aura un nombre d'identifiants correspondants qui réduirait les performances. J'étudie maintenant en utilisant le datahandler de SOLR qui pourrait faire le travail. Je vais devoir construire une base de données si. – Sfairas