2009-07-06 7 views
2

Mise à jourNhibernate.Search, Lucene, et l'API Critères: types inadéquation

J'ai regardé autour des NHibernate.Search.Tests projet pour savoir comment l'API critères est utilisé (je trouve il est extrêmement utile de regarder autour du code de test pour avoir des exemples de travail) et j'ai remarqué que la façon d'utiliser la recherche Fulltext est radicalement différente. Voici deux tests, l'un avec l'API de critères, dont une avec le schéma de requête classique:

[Test] 
     public void ResultSize() 
     { 
      IFullTextSession s = Search.CreateFullTextSession(OpenSession()); 
      ITransaction tx = s.BeginTransaction(); 
      // snipped the objects creation 

      QueryParser parser = new QueryParser("title", new StopAnalyzer()); 

      Lucene.Net.Search.Query query = parser.Parse("Summary:noword"); 
      IFullTextQuery hibQuery = s.CreateFullTextQuery(query, typeof(Clock), typeof(Book)); 
      Assert.AreEqual(0, hibQuery.ResultSize); 

// snipped the end of the test 
      } 

[Test] 
     public void UsingCriteriaApi() 
     { 
      IFullTextSession s = Search.CreateFullTextSession(OpenSession()); 
      ITransaction tx = s.BeginTransaction(); 
      // snipped creation 
      IList list = s.CreateCriteria(typeof(Clock)) 
       .Add(SearchRestrictions.Query("Brand:seiko")) 
       .List(); 
      Assert.AreEqual(1, list.Count, "should get result back from query"); 
     // snipped deletion 
     } 

La deuxième solution fonctionne sous vb.net, au prix de la requête Lucene utile (qui se lance dans sa propre totale des lignes correspondantes) et au coût de l'ordre Lucene (ou je ne pouvais pas trouver)


Bonjour à tous,

encore une fois, je suis perplexe sur le chemin, mais cette fois-ci , je soupçonne quelque chose un peu plus siniste r que mes habituelles erreurs erratiques

(de la musique sinistre cue) Je suis en train de combiner la recherche en utilisant Lucene.net FullText avec pagination et l'API critères. Jusqu'à présent, la pagination et la recherche Fulltext fonctionnaient parfaitement. Récemment cependant, nous avons dû utiliser l'API de critères pour ajouter des filtres spécifiques à la requête. Alors, que je l'ai fait était la suivante:

Créer l'objet de requête Nhibernate.Search en utilisant les éléments suivants

Private Function GetQuery(ByVal QueryString As String, ByVal Orders() As String) As IFullTextQuery 
     Dim ifts As IFullTextSession = Search.CreateFullTextSession(UnitOfWork.CurrentSession) 
     Dim analyzer As New SimpleAnalyzer 
     Dim parser As New MultiFieldQueryParser(SearchPropertyNames, analyzer) 
     Dim queryObj As Lucene.Net.Search.Query = parser.Parse(QueryString) 

     Dim nhsQuery As IFullTextQuery = ifts.CreateFullTextQuery(queryObj, New System.Type() {GetType(T)}) 
     For i As Integer = 0 To Orders.Count - 1 
      Orders(i) = Orders(i) & "FS" 
     Next 
     nhsQuery.SetSort(New Sort(Orders)) 

puis ajouter mes critères à la requête:

Dim crit As ICriteria = ifts.CreateCriteria(GetType(T)) 
     Dim criterion As ICriterion 
     If criteria IsNot Nothing Then 
      For Each criterion In criteria 
       If (Not criterion Is Nothing) Then 
        crit.Add(criterion) 
       End If 
      Next 
     End If 

nhsQuery.SetCriteriaQuery(crit) 

mais quand je liste le résultat requête, je reçois l'exception suivante

L'entité de requête de critère doit correspondre à l'entité de requête

Un coup d'oeil dans le fichier source FullTextQueryImpl (méthode GetLoader) montre qu'il y a une comparaison entre le nom du type donné à l'objet de requête NHibernate.Search et la EntityOrClassName biens pour les Critères objet . C'est là mes problèmes apparaissent parce que le FullTextQueryImpl utilise le Nom, et les critères utilise le Nom complet. Voici un code constructeur pour la CriteriaImpl classe

Public Sub New(ByVal persistentClass As Type, ByVal session As ISessionImplementor) 
    Me.New(persistentClass.FullName, CriteriaSpecification.RootAlias, session) 
    Me.persistentClass = persistentClass 
End Sub 

et ici la comparaison:

Dim entityOrClassName As String = DirectCast(Me.criteria, CriteriaImpl).EntityOrClassName 
      If ((Me.classes.GetLength(0) = 1) AndAlso (Me.classes(0).Name <> entityOrClassName)) Then 
       Throw New SearchException("Criteria query entity should match query entity") 
      End If 

En conséquence, la comparaison échoue et l'exception est levée. J'ai essayé de jouer avec les alias en vain puisque la comparaison n'utilise pas les alias.Est-ce qu'il me manque quelque chose d'énorme dans mon mélange de recherche Fulltext et l'API Criteria, ou est-ce quelque chose d'autre? Est-ce que cela fonctionne comme prévu en C#, parce que j'ai un sentiment étrange qu'il pourrait être lié à vb.net?

Merci pour la lecture,

Samy

+0

Samy, Avez-vous travaillé le problème ici? J'ai exactement le même problème? – NabilS

+0

Je n'ai pas creusé plus loin dans le code; J'ai plutôt utilisé la méthode SearchRestrictions.Query décrite ci-dessus. Fonctionne assez bien pour nos besoins. Bonne chance et n'hésitez pas à poster ici si vous trouvez la solution – samy

Répondre

1

On dirait que cela a été résolu avec la version 1611 de NHibernate.Search:

Révision: 1611

Message: Correction d'un bug où un nom de classe complet était comparé à un nom partiel. Cela provoquait l'échec de LuceneQueryTest.UsingCriteriaApi.

Modifié: /trunk/src/NHibernate.Search/src/NHibernate.Search/Query/FullTextQueryImpl.cs

svn: https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk/src/NHibernate.Search/

+0

Merci pour le heads-up. Le problème a été rendu discutable en utilisant une autre approche mais c'est agréable d'entendre que cela a été corrigé :) – samy