NHibernate + SqlServer全文搜索

Ana*_*and 5 c# sql-server nhibernate lucene.net full-text-search

我必须在NHibernate中进行全文搜索

对于以前的操作我以前使用的是Lucene.Net

我有一张名为候选人的表

对于全文查询,Lucene将从lucene索引返回所有候选Id并形成我在候选中查询的id并返回结果

但问题是有超过10个缺少候选简历可用,所以Lucene非常慢,因为10 Lk行的过滤值并且在查询中对候选者和再次过滤候选者的返回值花费了太多时间

我也有一个寻呼标准,每个页面我返回100个候选人

现在我在该表中添加了新表candidate_full_text我在sqlserver 2000中配置了全文索引现在我想使用NHibernate DetachedCriteria进行查询,如下所示

1) Select candidate with some filters

2) Execute the function ContainsTable for candidate_full_text table 
 (which returns candidate tables id as key and rank of occurrence of the search string)

3) join the result from 1 & 2

4) Apply paging criteria (ie return 1st 100,2nd 100,3rd 100.. etc) according to page no

5) return the result by order of rank column (which is return by ContainsTable)
Run Code Online (Sandbox Code Playgroud)

以下我在使用DetachedCriteria进行单一查询时必须做的事情而候选候选表的关键列是候选表id.这里我给出了1)候选(Min字段)的表模型

Id - int,

名称 - varchar,

Dob - 日期时间,

2)candidate_full_text

id - int,

candidate_resume_full_text -ntext,(配置的全文索引)

candidate_id - int

Joe*_*ano 2

如果您能够使用 SQL Server FTS 而不是 Lucene,并且性能可以接受,那么您可以利用在 SQL Server FTS 结果与数据库中其他关系数据之间进行关系联接的功能。要执行这些连接,您应该使用 CONTAINSTABLE 函数,而不是 CONTAINS 谓词。

使用您的示例,让我们在 SQL Server 中设置下表:

create table Candidate
( 
Id int primary key,
Name varchar(50),
Dob  datetime
)

create table Candidate_Full_Text
(
id int primary key,
candidate_resume_full_text ntext, -- FTS column
candidate_id int foreign key references Candidate(Id)
)
Run Code Online (Sandbox Code Playgroud)

然后,您可以在 nHibernate 中创建一个参数化命名查询,如下所示:

<sql-query name="CandidateSearch">
   <![CDATA[
     SELECT TOP (:take) * 
        FROM
            (SELECT c.Id, c.Name, ft.[RANK], ROW_NUMBER() OVER(ORDER BY ft.[RANK] desc) as rownum          
            FROM ContainsTable(Candidate_full_text, candidate_resume_full_text , :phrase, LANGUAGE 1033) ft
                        INNER JOIN Candidate c on ft.[KEY] = c.Id
            WHERE c.Name = :name and c.Dob > :dob
             ) a
        WHERE a.rownum > :skip ORDER BY a.rownum 
  ]]>
</sql-query>
Run Code Online (Sandbox Code Playgroud)

请注意此查询如何将 CONTAINSTABLE 函数的结果与数据库中的其他表相关联。通过使用 SQL FTS,可以轻松地将 FTS 结果与对数据库中其他数据的复杂关系查询连接起来。此功能是使用 SQL Server FTS 相对于 Lucene 的主要优势之一,并且可能是选择它而不是 Lucene 的一个原因,尽管它的整体性能较差。

最后,您可以在 C# 应用程序中填写参数并使用 nHibernate ISession 对象执行查询:

        int take = 5;
        int skip = 10;
        string phrase = "(team NEAR player) OR (teamwork NEAR coopertive)";
        string name = "John Doe";
        DateTime dob = new DateTime(1963, 7, 1);

        var results = _session.GetNamedQuery("ExpandedSearchTerm")
                              .SetString("phrase", phrase)
                              .SetDateTime("dob", dob)
                              .SetString("phrase", phrase)
                              .SetInt32("take", take)
                              .SetInt32("skip", skip)
                              .List();
Run Code Online (Sandbox Code Playgroud)

ROWNUMBER() 函数在您正在使用的 SQL Server 2000 中不可用,但我认为还有其他解决方法可以进行分页(例如参见本文)。(或者您可能希望将 SQL Server 升级到 2008,它在进程中运行 FTS 并且具有更好的性能!)

我认为沿着这些思路的解决方案将满足您的需求。