34 votes

Comment incorporer plusieurs champs dans QueryParser ?

Dim qp1 As New QueryParser("filename", New StandardAnalyzer())
Dim qp2 As New QueryParser("filetext", New StandardAnalyzer())
.
.

Au lieu de créer deux objets QueryParser distincts et de les utiliser pour obtenir deux objets Hits, est-il possible d'effectuer une recherche sur les deux champs à l'aide d'un seul objet QueryParser, de sorte que je n'aie qu'un seul objet Hits qui me donne le score global de chaque document.

77voto

Sam Doshi Points 2656

Il y a trois façons de procéder.

La première façon est de construire une requête manuellement, c'est ce que nous faisons. QueryParser fait en interne. C'est la façon la plus puissante de procéder, et cela signifie que vous n'avez pas besoin d'analyser l'entrée de l'utilisateur si vous voulez empêcher l'accès à certaines des fonctions les plus exotiques de l'interface utilisateur. QueryParser :

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);

BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("filename", "<text>"));
Query query2 = new TermQuery(new Term("filetext", "<text>"));
booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
booleanQuery.add(query2, BooleanClause.Occur.SHOULD);
// Use BooleanClause.Occur.MUST instead of BooleanClause.Occur.SHOULD
// for AND queries
Hits hits = searcher.Search(booleanQuery);

La deuxième façon est d'utiliser MultiFieldQueryParser ce qui se comporte comme QueryParser Il permet d'accéder à toute la puissance de ce dernier, à l'exception du fait qu'il effectue des recherches sur plusieurs champs.

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);

Analyzer analyzer = new StandardAnalyzer();
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(
                                        new string[] {"filename", "filetext"},
                                        analyzer);

Hits hits = searcher.Search(queryParser.parse("<text>"));

La dernière solution consiste à utiliser la syntaxe spéciale de l'option QueryParser voir ici .

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);    

Analyzer analyzer = new StandardAnalyzer();
QueryParser queryParser = new QueryParser("<default field>", analyzer);
// <default field> is the field that QueryParser will search if you don't 
// prefix it with a field.
string special = "filename:" + text + " OR filetext:" + text;

Hits hits = searcher.Search(queryParser.parse(special));

L'autre option consiste à créer un nouveau champ lors de l'indexation de votre contenu, appelé filenameandtext, dans lequel vous pouvez placer le contenu du fichier les deux filename et filetext, il suffit alors de rechercher un seul champ.

4voto

Bob King Points 12913

Il suffit de construire une chaîne de requête avec chaque terme :

"filename:searchText OR filetext:searchText"

Ce que vous passez comme champ initial dans le constructeur de QueryParser n'a pas d'importance. Assurez-vous simplement d'appeler .Parse() sur votre chaîne de requête pour obtenir un objet Query à exécuter.

Si vous voulez utiliser une recherche "et" :

"+filename:searchText +filetext:searchText"

2voto

vijay shiyani Points 219

** vous pouvez également utiliser MultiFieldQueryParser pour rechercher dans tous les champs disponibles.**

Par exemple

Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29, 
indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)

Voici un exemple complet.

//get index directory
Dim directory As Directory = FSDirectory.Open(New DirectoryInfo(HostingEnvironment.MapPath(VirtualIndexPath)))

//get analyzer
Dim analyzer As Analyzer = New StandardAnalyzer(Version.LUCENE_29)

//get index reader and searcher
Dim indexReader__1 As IndexReader = IndexReader.Open(directory, True)
Dim indexSearch As Searcher = New IndexSearcher(indexReader__1)

//add all possible fileds in multifieldqueryparser using indexreader getFieldNames method
Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29, indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)
Dim query = queryParser.Parse(Criteria)
Dim resultDocs As TopDocs = Nothing

//perform search
resultDocs = indexSearch.Search(query, indexReader__1.MaxDoc())
Dim hits = resultDocs.scoreDocs

J'espère que cela vous aidera

1voto

Saltire Points 324

Pour chaque champ, créez une requête à partir des analyseurs de requêtes ci-dessus, puis ajoutez la requête à une requête booléenne indiquant qu'elle "doit" apparaître.

Vous pouvez également consulter le MultiFieldQueryParser, qui offre une méthode simplifiée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X