• Spring.net整合Lucene.net 实现全文检索(附例程)转载


    什么是Lucene.net?

    引用wikipedia上的介绍:“Lucene是一套用于全文检索和搜尋的開放源碼程式庫,由Apache软件基金会支持和提供。Lucene提供了一個簡單卻強大的應用程式介面,能夠做全文索引和搜尋...”

    而Lucene.net便是Lucene在dot net平台上的移植版本。关于Lucene的一些概念,有兴趣的朋友可以参考这里

    要实现Spring.net与Lucene.net的整合,关键点在于:

    1、查询时,使用Spring.net集成的nHibernate来管理Lucene.net使用的Session;

    2、对数据实体的CRUD进行事件监控,以便动态更新索引

    经过一番尝试,决定将原有的框架进行升级——spring.net 1.2.0 + nHibernaet 2.0.1 + Lucene.net 2.0 + nHibernate.Search。

    ok,看看都需要进行哪些调整:

    一、实体生成模板加上索引

    在model层引用nHibernate.Search程序集,它的作用是根据实体上的元标记,选择是否为实体开启存储空间,以及索引的字段范围。

    修改codeSmith中的nHibernate Template,像这样,用以将主键和字符型字段进行索引:



    <%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Generates a C# class for use with NHibnate" %>
    <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="Table that the mapping file is based on" %>
    <%@ Property Name="Namespace" Type="System.String" Default="MyNamespace.Data" Category="Object" Description="The class namespace that the mapping file should use" %>
    <%@ Property Name="Assembly" Type="System.String" Default="MyApp.MyAssembly" Category="Object" Description="The assembly that the class will be used in" %>
    <%@ Property Name="RemoveTablePrefix" Type="System.String" Default="tbl" Category="Object" Description="The prefix to remove from table names" %>
    <%@ Property Name="ForceId" Type="System.Boolean" Default="true" Category="Object" Description="Force Id for identity column" %>
    <%@ Assembly Name="SchemaExplorer" %>
    <%@ Assembly Name="System.Data" %>
    <%@ Import Namespace="SchemaExplorer" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Text.RegularExpressions" %>
    using System;
    using System.Collections.Generic;
    using NHibernate.Search.Attributes;
    using NHibernate.Search;

    namespace <%= Namespace %>
    {
        
    #region <%= ClassName(SourceTable) %>

        
    /// <summary>
        
    /// <%= ClassName(SourceTable) %> object for NHibernate mapped table '<%= ClassTable(SourceTable) %>'.
        
    /// </summary>
        [Serializable]
        [TableInfo(TableName 
    = "<%= ClassTable(SourceTable) %>", PrimaryKey = "<%= ColumnName(SourceTable.PrimaryKey.MemberColumns[0])%>" , Columns="<% for(int i=0;i<SourceTable.Columns.Count;i++) {%><%=ColumnName(SourceTable.Columns[i]) + (i==SourceTable.Columns.Count-1 ? "":",") %><%}%>")]
        [Indexed(Index 
    = "<%= ClassName(SourceTable) %>")] 
        
    public class <%= ClassName(SourceTable) %>
        {
            
    #region Member Variables
            
            
    <% if (SourceTable.PrimaryKey.MemberColumns.Count == 1) {%>
            
    protected <%= IdMemberType(SourceTable) %> <%= IdMemberName(SourceTable) %>;
            
    <% } %>        
            
    <% foreach(ColumnSchema column in SourceTable.NonKeyColumns) { %>
            
    protected <%= MemberType(column) %> <%= MemberName(column) %>;
            
    <% } %>
            
    <% foreach (TableKeySchema foreignKey in SourceTable.ForeignKeys) { %>
            
    protected <%= ManyToOneClass(foreignKey) %> <%= ManyToOneMemberName(foreignKey) %>;
            
    <% if ((foreignKey.ForeignKeyTable == SourceTable) && (foreignKey.PrimaryKeyTable == SourceTable)) { %>
            
    protected <%= CollectionType(foreignKey)%> <%= CollectionMemberName(foreignKey)%>;
            
    <% } %>
            
    <% } %>
            
    <% foreach(TableKeySchema primaryKey in SourceTable.PrimaryKeys) { %>
            
    <% if (IsManyToManyTable(primaryKey.ForeignKeyTable)) { %>
            
    protected <%= CollectionType(primaryKey)%> <%= CollectionManyToManyMemberName(primaryKey)%>;
            
    <% } else if (IsOneToOneTable(primaryKey)) { %>
            
    protected <%= OneToOneClass(primaryKey) %> <%= OneToOneMemberName(primaryKey) %>;
            
    <% } else if (IsSubClassTable(primaryKey)) { %>
            
    <% } else { %>
            
    protected <%= CollectionType(primaryKey)%> <%= CollectionMemberName(primaryKey)%>;
            
    <% } %>
            
    <% } %>

            
    #endregion

            
    #region Constructors

            
    public <%= ClassName(SourceTable) %>() { }

            
    public <%= ClassName(SourceTable) %><%
                
    int count = 0;
                
    foreach(ColumnSchema column in SourceTable.NonKeyColumns)
                {
                    
    if (count > 0) Response.Write("");
                    
    %><%= MemberType(column) %> <%= ParameterName(column) %><%
                    count 
    ++;
                }
                
    foreach(TableKeySchema foreignKey in SourceTable.ForeignKeys)
                {
                    
    if (count > 0) Response.Write("");
                    
    %><%= ManyToOneClass(foreignKey) %> <%= ManyToOneParameterName(foreignKey) %><%
                    count 
    ++;
                }
                
    %> )
            {
            
    <% foreach(ColumnSchema column in SourceTable.NonKeyColumns) { %>
                
    this.<%= MemberName(column) %> = <%= ParameterName(column) %>;
            
    <% } %>
            
    <% foreach(TableKeySchema foreignKey in SourceTable.ForeignKeys) { %>
                
    this.<%= ManyToOneMemberName(foreignKey) %> = <%= ManyToOneParameterName(foreignKey) %>;
            
    <% } %>
            }

            
    #endregion

            
    #region Public Properties

            
    <% if (SourceTable.PrimaryKey.MemberColumns.Count == 1) {%>
            [DocumentId]
            
    public <%= IdMemberType(SourceTable) %> <%= IdName(SourceTable) %>
            {
                
    get {return <%= IdMemberName(SourceTable) %>;}
                
    <% if (IdMemberType(SourceTable) == "string" ) {%>
                
    set
                {
                    
    if ( value != null && value.Length > <%= ColumnLength(SourceTable.PrimaryKey.MemberColumns[0])%>)
                        
    throw new ArgumentOutOfRangeException("Invalid value for <%= IdName(SourceTable) %>", value, value.ToString());
                    
    <%= IdMemberName(SourceTable) %> = value;
                }
                
    <% } else { %>
                
    set {<%= IdMemberName(SourceTable) %> = value;}
                
    <% } %>
            }
            
    <% } %>

            
    <% foreach(ColumnSchema column in SourceTable.NonKeyColumns) { %>
            
    <%if( MemberType(column) =="string"){%>
            [Field(Index.Tokenized, Store 
    = Store.Yes)]
            
    <%}%>
            
    public <%= MemberType(column) %> <%= PropertyName(column) %>
            {
                
    get { return <%= MemberName(column) %>; }
                
    <% if (MemberType(column) == "string") {%>
                
    set
                {
                    
    <% if(ColumnLength(column) != "16" ){ %>
                    
    if ( value != null && value.Length > <%= ColumnLength(column)%>)
                        
    throw new ArgumentOutOfRangeException("Invalid value for <%= PropertyName(column) %>", value, value.ToString());
                    
    <%}%>    
                    
    <%= MemberName(column) %> = value;
                }
                
    <% } else { %>
                
    set { <%= MemberName(column) %> = value; }
                
    <% } %>
            }

            
    <% } %>
            
    <% foreach(TableKeySchema foreignKey in SourceTable.ForeignKeys) { %>
            
    public <%= ManyToOneClass(foreignKey) %> <%= ManyToOneName(foreignKey) %>
            {
                
    get { return <%= ManyToOneMemberName(foreignKey) %>; }
                
    set { <%= ManyToOneMemberName(foreignKey) %> = value; }
            }

            
    <% if ((foreignKey.ForeignKeyTable == SourceTable) && (foreignKey.PrimaryKeyTable == SourceTable)) { %>
            
    public <%= CollectionType(foreignKey) %> <%= CollectionName(foreignKey) %>
            {
                
    get { return <%= CollectionMemberName(foreignKey) %>; }
                
    set { <%= CollectionMemberName(foreignKey) %> = value; }
            }

            
    <% } %>
            
    <% } %>
            
    <% foreach(TableKeySchema primaryKey in SourceTable.PrimaryKeys) { %>
            
    <% if (IsManyToManyTable(primaryKey.ForeignKeyTable)) { %>
            
    public <%= CollectionType(primaryKey) %> <%= CollectionManyToManyName(primaryKey) %>
            {
                
    get
                {
                    
    if (<%= CollectionManyToManyMemberName(primaryKey) %>==null)
                        {
                        
    <%= CollectionManyToManyMemberName(primaryKey) %> = <%= NewCollectionType(primaryKey) %>;
                    }
                    
    return <%= CollectionManyToManyMemberName(primaryKey) %>;
                }
                
    set { <%= CollectionManyToManyMemberName(primaryKey) %> = value; }
            }

            
    <% } else if (IsOneToOneTable(primaryKey)) { %>
            
    public <%= OneToOneClass(primaryKey) %> <%= OneToOneName(primaryKey) %>
            {
                
    get { return <%= OneToOneMemberName(primaryKey) %>; }
                
    set { <%= OneToOneMemberName(primaryKey) %> = value; }
            }

            
    <% } else if (IsSubClassTable(primaryKey)) { %>
            
    <% } else { %>
            
    public <%= CollectionType(primaryKey) %> <%= CollectionName(primaryKey) %>
            {
                
    get
                {
                    
    if (<%= CollectionMemberName(primaryKey) %>==null)
                    {
                        
    <%= CollectionMemberName(primaryKey) %> = <%= NewCollectionType(primaryKey) %>;
                    }
                    
    return <%= CollectionMemberName(primaryKey) %>;
                }
                
    set { <%= CollectionMemberName(primaryKey) %> = value; }
            }

            
    <% } %>
            
    <% } %>
            

            
    #endregion
            
    <% foreach(TableKeySchema primaryKey in SourceTable.PrimaryKeys) { %>
            
    <% if (IsManyToManyTable(primaryKey.ForeignKeyTable)) { } %>
            
    <% else if (IsSubClassTable(primaryKey)) { %>

        
    #region <%= JoinedSubclassName(primaryKey) %>

        
    /// <summary>
        
    /// <%= JoinedSubclassName(primaryKey) %> object for NHibernate mapped table '<%= JoinedSubclassTable(primaryKey) %>'.
        
    /// </summary>
        public class <%= JoinedSubclassName(primaryKey) %> : <%= ClassName(SourceTable) %>
        {
            
    #region Member Variables

            
    <% foreach(ColumnSchema column in primaryKey.ForeignKeyTable.NonKeyColumns) { %>
            
    protected <%= MemberType(column) %> <%= MemberName(column) %>;
            
    <% } %>
            
    <% foreach (TableKeySchema foreignKey in primaryKey.ForeignKeyTable.ForeignKeys) { %>
            
    <% if (foreignKey.PrimaryKeyTable != SourceTable) { %>
            
    protected <%= ManyToOneClass(foreignKey) %> <%= ManyToOneMemberName(foreignKey) %>;
            
    <% } %>
            
    <% if ((foreignKey.ForeignKeyTable == primaryKey.ForeignKeyTable) && (foreignKey.PrimaryKeyTable == primaryKey.ForeignKeyTable)) { %>
            
    protected <%= CollectionType(foreignKey)%> <%= CollectionMemberName(foreignKey)%>;
            
    <% } %>
            
    <% } %>

            
    #endregion

            
    #region Constructors

            
    public <%= JoinedSubclassName(primaryKey) %>() : base() { }

            
    public <%= JoinedSubclassName(primaryKey) %><%
                count 
    = 0;
                
    foreach(ColumnSchema column in SourceTable.NonKeyColumns)
                {
                    
    if (count > 0) Response.Write("");
                    
    %><%= MemberType(column) %> <%= ParameterName(column) %><%
                    count 
    ++;
                }
                
    foreach(TableKeySchema foreignKey in SourceTable.ForeignKeys)
                {
                    
    if (count > 0) Response.Write("");
                    
    %><%= ManyToOneClass(foreignKey) %> <%= ManyToOneParameterName(foreignKey) %><%
                    count 
    ++;
                }
                
    foreach(ColumnSchema column in primaryKey.ForeignKeyTable.NonKeyColumns)
                {
                    
    if (count > 0) Response.Write("");
                    
    %><%= MemberType(column) %> <%= ParameterName(column) %><%
                    count 
    ++;
                }
                
    foreach(TableKeySchema foreignKey in primaryKey.ForeignKeyTable.ForeignKeys)
                {
                    
    if (foreignKey.PrimaryKeyTable != SourceTable)
                    {
                        
    if (count > 0) Response.Write("");
                        
    %><%= ManyToOneClass(foreignKey) %> <%= ManyToOneParameterName(foreignKey) %><%
                        count 
    ++;
                    }
                }
                
    %> ) : base(<%
                count 
    = 0;
                
    foreach(ColumnSchema column in SourceTable.NonKeyColumns)
                {
                    
    if (count > 0) Response.Write("");
                    
    %><%= ParameterName(column) %><%
                    count 
    ++;
                }
                
    foreach(TableKeySchema foreignKey in SourceTable.ForeignKeys)
                {
                    
    if (count > 0) Response.Write("");
                    
    %><%= ManyToOneParameterName(foreignKey) %><%
                    count 
    ++;
                }
                
    %>)
            {
            
    <% foreach(ColumnSchema column in primaryKey.ForeignKeyTable.NonKeyColumns) { %>
                
    this.<%= MemberName(column) %> = <%= ParameterName(column) %>;
            
    <% } %>
            
    <% foreach (TableKeySchema foreignKey in primaryKey.ForeignKeyTable.ForeignKeys) { %>
            
    <% if (foreignKey.PrimaryKeyTable != SourceTable) { %>
                
    this.<%= ManyToOneName(foreignKey) %> = <%= ManyToOneParameterName(foreignKey) %>;
            
    <% } %>
            
    <% } %>
            }

            
    #endregion

            
    #region Public Properties

            
    <% foreach(ColumnSchema column in primaryKey.ForeignKeyTable.NonKeyColumns) { %>
            
    public <%= MemberType(column) %> <%= PropertyName(column) %>
            {
                
    get { return <%= MemberName(column) %>; }
                
    set { <%= MemberName(column) %> = value; }
            }

            
    <% } %>
            
    <% foreach(TableKeySchema foreignKey in primaryKey.ForeignKeyTable.ForeignKeys) { %>
            
    <% if (foreignKey.PrimaryKeyTable != SourceTable) { %>
            
    public <%= ManyToOneClass(foreignKey) %> <%= ManyToOneName(foreignKey) %>
            {
                
    get { return <%= ManyToOneMemberName(foreignKey) %>; }
                
    set { <%= ManyToOneMemberName(foreignKey) %> = value; }
            }

            
    <% } %>
            
    <% if ((foreignKey.ForeignKeyTable == primaryKey.ForeignKeyTable) && (foreignKey.PrimaryKeyTable == primaryKey.ForeignKeyTable)) { %>
            
    public <%= CollectionType(foreignKey) %> <%= CollectionName(foreignKey) %>
            {
                
    get { return <%= CollectionName(foreignKey) %>; }
                
    set { <%= CollectionName(foreignKey) %> = value; }
            }

            
    <% } %>
            
    <% } %>
            
    #endregion
        }

        
    #endregion
            
    <% } %>
            
    <% } %>
        }
        
    #endregion
    <!-- #include file="NHibernate.inc" -->
    }

    在例程包中的“其他”目录中,有完整的生成模板。

    二、集成环境配置

    修改web.config,进行Spring.net和nHibernate.Search的配置: 

    web.config

     此处的"hibernate.search.default.indexBase"值"~/Index"可以更改为您希望的目录名称。这里的意义在于,当监控到数据变化时,会将索引变化写入到"~/Index/实体名/“。

    在nHibernate 2.0中,加入了对数据库事件的监控,在配置文件中,给集成环境中的SessionFactory加上"EventListeners" 属性,便可轻松捕捉到诸如Insert、Update、Delete等事件,交由nHibernate.Search进行索引处理:  


    appDaoContext.xml

    三、全文搜索

    给数据访问模板DaoTemplate添加一个全文搜索的方法:

    /// <summary>
            
    /// 全文检索
            
    /// </summary>
            
    /// <typeparam name="T">类型</typeparam>
            
    /// <param name="query">关键词</param>
            
    /// <returns></returns>

            IList FullTextSearch(string query)


    四、运行一下

    Insert对象:

     

     Search:

     

    随笔写得很粗糙,大部分细节在附件的例程包中(包括数据库备份,模板,项目文件),如果有兴趣,还是参考实例吧:
  • 相关阅读:
    webserivice---通过Ajax访问远程天气预报服务
    IDEA Error:java: 未结束的字符串文字
    UML:它是一种支持模型化和软件系统开发的图形化语言
    核心代码之分页
    struts.xml 的 file 报错 解决方式
    Myeclipse buildpath 加server lib (server runtime)
    核心代码之优化查询
    入园新编
    为啥JS中判断对象是否是类的实例推荐使用instanceof而不推荐constructor
    http常考的题目
  • 原文地址:https://www.cnblogs.com/chenying99/p/2167987.html
Copyright © 2020-2023  润新知