zoukankan      html  css  js  c++  java
  • 网站全文检索设计

    1、架构设计
    采 用OLTP交易数据库和OLAP数据仓库(用于搜索和分析)分离的模式,OLTP作为OLAP的数据源通过SQL Server Integration Services (SSIS)定期导入到OLAP数据仓库环境中,OLAP采用星型结构以便于更好地满足搜索和将来的数据挖掘。 OLAP数据仓库的建立目标为了检索和数据挖掘,故其事实表的建立可以反范式原则设计。

      

    SQL Server 2005全文检索技术在网站上的应用实录
    图2

      2、原型设计(由于篇幅限制,这里仅给出搜索主页和主要资源查询页面)

      

    SQL Server 2005全文检索技术在网站上的应用实录
    图3

      3、数据库设计

      

    SQL Server 2005全文检索技术在网站上的应用实录
    图4

      4、数据字典

      MainInfoTab(信息主表)

      SQL Server 2005全文检索技术在网站上的应用实录

      CapitalInfoTab(资本信息明细表)

      SQL Server 2005全文检索技术在网站上的应用实录

      ProjectInfoTab(项目信息明细表)

      SQL Server 2005全文检索技术在网站上的应用实录

      MerchantInfoTab(政府招商信息明细表)

      SQL Server 2005全文检索技术在网站上的应用实录

      四、数据库全文检索实现

      至此,我们已经完成了全文检索的设计工作,现在可以来实现它的功能啦!

      首先, 让我们建立检索表的全文检索,全文检索要求唯一索引,故需要在相关表建立唯一聚集索引。

      第二步,使用SQL DDL或者SQL Server Management Studio建立表的全文检索。

      1)使数据库支持全文检索。

      

    SQL Server 2005全文检索技术在网站上的应用实录
    图5

      或者通过键入命令 EXEC SP_FULLTEXT_DATABASE 'Enable' 命令达到同样效果。

      2)定义表的全文检索目录和索引字段。

      在表的鼠标右键通过点击“全文检索定义全文检索”将弹出如下执行向导,本向导执行完毕则该表的全文检索业已完毕。

      a)选择要索引的字段

      

    SQL Server 2005全文检索技术在网站上的应用实录
    图6

      或者键入如下命令:

      

    CREATE FULLTEXT INDEX ON TableName KEY INDEX PK_IndexName ON DB WITH CHANGE_TRACKING AUTO
    ALTER FULLTEXT INDEX ON TableName ADD ColumnName

      b)选择或创建新的索引目录。

      

    SQL Server 2005全文检索技术在网站上的应用实录
    图7

      c)定义填充计划。

      

    SQL Server 2005全文检索技术在网站上的应用实录
    图8

      至此,表的全文索引已经建立完毕,表示只要键入SQL 指令就可以完成全文检索功能。

      第三步,开发存储过程并把结果集分页,以供前台页面调用返回查询的结果。

      1) 建立找资本全文检索储存过程USP_CaptialInfo_FullIndex。

    /*
    找资本全文索引开发过程 
    */
    CREATE PROCEDURE USP_CaptialInfo_FullIndex
    (
    @TableViewQueryNameVarchar( 1024 ), --传入的查询字符窜
    @SearchKeyword nvarchar(100), --传入的查询关键字
    @SelectStr Varchar( 500 ), --选择列字符串
    @Criteria Varchar( 8000 ), --查询条件
    @Sort Varchar( 255 ), --排序字符串
    @FristTopNum int,  --显示的第一页置顶的数目
    @Page bigint OUTPUT , --显示的当前页号
    @CurrentPageRowbigint,  --页大小(显示多少行) 
    @TotalCount bigint output, --通过该查询条件,返回的查询记录的总页数
    @Totaltimes bigint output --所有搜索时间,以秒为单位
    )
    as 
    DECLARE @starttime datetime,
    @endtime datetime
    SELECT @starttime = getdate()
    IF ISNULL(@SearchKeyword,'') !='' OR RTRIM(@SearchKeyword)!=''
    BEGIN
    SET @TableViewQueryName =
    ' SELECT '+
    ' ROW_NUMBER() OVER (ORDER BY RANK DESC) AS SerialNumber ,'+
    ' F.[rank], '+
    ' p.*' +
    ' FROM'+
    ' FREETEXTTABLE( CapitalInfoFactTab , (ProvinceName, CityName, 
    CountyName, Keyword,Title ,IndustryBName , shortcontent, ComAbout , ComBreif) ,
    '+ ''''+@SearchKeyword+ ''''+') AS f '+
    ' INNER JOIN  CapitalInfoFactTab  AS p '+
    ' ON f.[key] = p.infoID '
    EXEC [USP_GetFrontDataList_ByFullIndex] @TableViewQueryName,
    @SearchKeyword, @SelectStr, @Criteria, @Sort, @FristTopNum,
    @Page OUTPUT , @CurrentPageRow , @TotalCount OUTPUT
    END ELSE BEGIN
    EXEC dbo.GetFrontDataList 'dbo.ProjectInfoFactTab', 'InfoID',
    @SelectStr,@Criteria,@Sort,0, @Page output, @CurrentPageRow,
    @TotalCount output
    END
    SELECT @endtime = getdate()
    SELECT @Totaltimes = DATEdiff(Ms, @starttime ,@endtime)
    RETURN

      2)建立通用分页存过程[USP_GetFrontDataList_ByFullIndex]。由于性能考虑,返回给前台页面需要网站数据库端即完成分页。

      

    CREATE PROCEDURE [dbo].[USP_GetFrontDataList_ByFullIndex]
    (
    @TableViewQueryName Varchar( 1024 ),
      --Table或View或者Query的名字或字符串
    @Key  Varchar( 50 ), --关键字
    @SelectStr  Varchar( 500 ),  --选择列字符串
    @Criteria  Varchar( 8000 ),--查询条件
    @Sort  Varchar( 255 ), --排序字符串
    @FristTopNum  INT,   --显示的第一页置顶的数目
    @Page  BIGINT OUTPUT, --显示的当前页号
    @CurrentPageRow BIGINT, --页大小(显示多少行)
    @TotalCount  BIGINT OUTPUT  --通过该查询条件,返回的查询记录的总页数
    )
    AS
    SET NOCOUNT ONif charindex(';',@Criteria)>0 or charindex('--',@Criteria)>0 or charindex('/*',@Criteria)>0 or
    charindex('*/',@Criteria)>0 or charindex('syscolumns',@Criteria)>0 or
    charindex('sysfiles',@Criteria)>0
    or charindex('char(124)',@Criteria)>0 or charindex('1=1',@Criteria)>0
    RETURN
    DECLARE @TotalStr nVarchar(4000)
    DECLARE @Str  nVarchar(4000)
    DECLARE @TopRowNum bigint
    IF @SelectStr IS NULL AND
    RTRIM(LTRIM(@Criteria)) = ''
    SET @SelectStr = '*'
    IF @FristTopNum IS NULL AND @FristTopNum < 0
    BEGIN
    SET @FristTopNum = 0
    END
    ELSE IF @FristTopNum > @CurrentPageRow
    BEGIN
    SET @FristTopNum = @CurrentPageRow
    END
    IF @CurrentPageRow > 0
    BEGIN
    IF @Criteria IS NOT NULL AND
    RTRIM(LTRIM(@Criteria)) <> ''
    BEGIN
    SET @TotalStr = 'SELECT @TotalCount=COUNT(*) FROM ' +
    '('+ @TableViewQueryName  +')'+ ' T '
    + ' WHERE ' + @Criteria
    END
    ELSE
    BEGIN
    SET @TotalStr = 'SELECT @TotalCount=COUNT(*) FROM ' +
    '('+@TableViewQueryName +')'+ ' T '
    END
    PRINT @TotalStr
    EXEC sp_ExecuteSql @TotalStr, N'@TotalCount bigint output',@TotalCount output
    SET @TotalCount = @TotalCount + isnull(@FristTopNum ,0)
    DECLARE @TotalPage bigint
    SET @TotalPage = @TotalCount/@CurrentPageRow
    IF @TotalCount%@CurrentPageRow > 0
    BEGIN
    SET @TotalPage = @TotalPage + 1
    END
    IF @Page <= 0
    BEGIN
    SET @Page = 1
    END
    IF @TotalPage > 0 AND
    @Page > @TotalPage
    BEGIN
    SET @Page = @TotalPage
    END
    --组织查询语句
    SET @Str = 'SELECT  ' +  @SelectStr + ' FROM (' + 
    @TableViewQueryName + ') T WHERE T.SerialNumber >' +
    cast ((@Page-1) as varchar(10)) + '*' +cast( @CurrentPageRow as varchar(10))+ 
    ' AND T.SerialNumber <= '+
    cast (@Page as varchar(10)) + '*' +cast( @CurrentPageRow as varchar(10))
    IF @Sort IS NOT NULL ANDRTRIM(LTRIM(@Sort)) <> ''
    BEGIN
    IF @Criteria IS NOT NULL AND RTRIM(LTRIM(@Criteria)) <> ''
    BEGIN
    SET @Str = @Str +  ' AND (' + @Criteria + ') ORDER BY '+@Sort
    END
    ELSE
    BEGIN
    SET @Str = @Str +  ' AND (' + @Criteria + ') ORDER BY '+@Sort
    END
    END
    ELSE
    BEGIN
    IF @Criteria IS NOT NULL AND  RTRIM(LTRIM(@Criteria)) <> ''
    BEGIN
    SET @str = @str + ' AND (' + @Criteria + ') ' 
    END
    END
    --对无记录时当前页数的处理
    IF @TotalCount=0
    BEGIN
    SET @Page = 0
    END
    END
    EXEC sp_ExecuteSql @Str

    由于本行业网站可以提高如下几类信息资源,现列表分示如下:
    ID检索内容数据表检索命令示例
    1投资CapitalInfoTabDECLARE @RC int
    DECLARE @TableViewQueryName varchar(1024)
    DECLARE @SearchKeyword nvarchar(100)
    DECLARE @SelectStr varchar(500)
    DECLARE @Criteria varchar(8000)
    DECLARE @Sort varchar(255)
    DECLARE @FristTopNum int
    DECLARE @Page bigint
    DECLARE @CurrentPageRow bigint
    DECLARE @TotalCount bigint
    DECLARE @Totaltimes bigint
     
    -- TODO: 在此处设置参数值。
    SET @SearchKeyword = '地产项目'
    SET @SelectStr = '*'
    SET @Sort = ''
    SET @Page= 1
    SET @CurrentPageRow = 20

    EXECUTE @RC = [InvestDM].[dbo].USP_CapitalInfo_FullIndex
      @TableViewQueryName
     ,@SearchKeyword
     ,@SelectStr
     ,@Criteria
     ,@Sort
     ,@FristTopNum
     ,@Page 
     ,@CurrentPageRow
     ,@TotalCount OUTPUT
     ,@Totaltimes OUTPUT
    SELECT @Page,@TotalCount,@Totaltimes
    2融资ProjectInfoTabDECLARE @SearchKeyword nvarchar(100) --传入的查询关键字
    SET   @SearchKeyword = '深圳'
     
    SELECT p.title,
    p.infoid,
    f.[rank] ,
    keyword,title,provinceName,cityName,CountyName

    FROM
    FREETEXTTABLE([ProjectInfoFactTab], (provinceName,cityName,CountyName,keyword,title), @SearchKeyword) AS f
    INNER JOIN [ProjectInfoFactTab] AS p
    ON f.[key] = p.infoID
    ORDER BY RANK DESC
    3招商MerchantInfoTab  DECLARE @SearchKeyword nvarchar(100) --传入的查询关键字
      SET   @SearchKeyword = '深圳'
      SELECT 
    ROW_NUMBER() OVER (ORDER BY RANK DESC) AS SerialNumber ,
    F.[rank],
    p.*
    FROM
    FREETEXTTABLE( MerchantInfoFactTab , (ProvinceName, CityName,  CountyName, Keyword,

      Title ,IndustryBName , shortcontent, ZoneAbout , ZoneAboutBrief, MerchantTypeName ,MerchantAttributeName,

      CooperationDemandName ) ,

      @SearchKeyword) AS f

    INNER JOIN  MerchantInfoFactTab  AS p 
    ON f.[key] = p.infoID
    4资讯NewsTab   DECLARE @SearchKeyword nvarchar(100) --传入的查询关键字
       SET   @SearchKeyword = '深圳'
       SELECT 
     ROW_NUMBER() OVER (ORDER BY RANK DESC) AS SerialNumber ,
    F.[rank] ,
     p.* 
    FROM 
     FREETEXTTABLE( NewsInfoFactTab , (AreaName,  Keyword, 
     Title , DisplayTitle, subtitle ,Summary , Content ,NewsIndustryName ,  NewsTypeName ) , @SearchKeyword ) AS f
    INNER JOIN  NewsInfoFactTab  AS p 
     ON f.[key] = p.infoID 
  • 相关阅读:
    Linux学习-汇总
    前端学习-汇总
    人生苦短,我用python
    python_面试题_DB相关问题
    企业应用学习-git学习
    python基础-并发编程之I/O模型基础
    python_面试题_HTTP基础相关问题
    python_面试题_TCP的三次握手与四次挥手问题
    好的RESTful API的设计原则
    CSP-S2021 游记
  • 原文地址:https://www.cnblogs.com/0000/p/1576548.html
Copyright © 2011-2022 走看看