zoukankan      html  css  js  c++  java
  • 解决HubbleDotNet搜索引擎索引数据不全的问题

          HubbleDotnet是国产.NET平台搜索引擎的翘楚,开放源代码,使用方便,不过我一直在非生产环境下使用。官方网页在HubbleDotNet开源全文搜索数据库项目--技术详解.

          以前当数据库使用Mysql的时候没问题,但当使用了MonogoDB做数据源之后,经常出现数据无法全部自动索引的情况。比如有10W的表,常常只能索引到3W甚至更少,乃至每次索引的数量都不同。

      这件事拖了我很久,万不得已看日志查源代码,才发现是一个程序上的bug.

      系统日志记录如下:

    LogTime:2015-01-06 16:43:32.773
    Process:HubbleTask
    Message:ErrMsg:Get documents for insert fail!
    Exception:System.ArgumentException
    Message:列“Year”不属于表 Table1。
    Stack:   在 System.Data.DataRow.GetDataColumn(String columnName)
       在 System.Data.DataRow.get_Item(String columnName)
       在 Hubble.Core.Service.SynchronizeCanUpdate.GetOneRowDocument(DataRow row) 位置 d:CodesC#OpenSourceshubbledotnet-100319C#srcHubble.DataHubble.CoreServiceSynchronizeCanUpdate.cs:行号 300
       在 Hubble.Core.Service.SynchronizeCanUpdate.GetDocumentsForInsert(IDBAdapter dbAdapter, Int64& from) 位置 d:CodesC#OpenSourceshubbledotnet-100319C#srcHubble.DataHubble.CoreServiceSynchronizeCanUpdate.cs:行号 471
       在 Hubble.Core.Service.SynchronizeCanUpdate.DoGetDocumentsForInsertAsync(Object dbAdapter) 位置 d:CodesC#OpenSourceshubbledotnet-100319C#srcHubble.DataHubble.CoreServiceSynchronizeCanUpdate.cs:行号 425

        找到对应的源代码,SynchronizeCanUpdate.cs,位置如下:

      foreach (Field field in _DBProvider.Table.Fields)
                {
                    if (field.IndexType == Field.Index.None)
                    {
                        if (!_DBProvider.Table.HasMirrorTable)
                        {
                            continue;
                        }
                    }
    
                    string value = null;
    
                    if (row[field.Name] == DBNull.Value)  //此处出错
                    {
                        if (!field.CanNull)
                        {
                            throw new DataException(string.Format("Field:{0} in table {1} is not null so that it can't be inserted null value!",
                                field.Name, _DBProvider.Table.Name));
                        }
    
                        if (field.DefaultValue == null)
                        {
                            if (field.IndexType != Field.Index.None)
                            {
                                throw new DataException(string.Format("Field:{0} in table {1} is null but hasn't default value so that it can't be inserted null value!",
                                    field.Name, _DBProvider.Table.Name));
                            }
                        }
    
                        value = field.DefaultValue;
                    }
                    else
                    {
                        if (row[field.Name] is DateTime)
                        {
                            value = ((DateTime)row[field.Name]).ToString("yyyy-MM-dd HH:mm:ss.fff");
                        }
                        else
                        {
                            value = row[field.Name].ToString();
                        }
                    }
    
                    document.Add(field.Name, value, field.DataType, field.DataLength, false);
                }

          很清楚,DataRow中,没有Year这个字段。但是我在建立索引 表的时候,是添加了一个可空字段Year的啊,更何况,其他条数据的索引都没问题,但就会遇到一些数据Row没有Year. 字段。可能是HubbleDotnet对MongoDb的驱动支持不够完善吧,在中间的转换出了问题,改进也很简单:

      

    foreach (Field field in _DBProvider.Table.Fields)
                {
                    if (field.IndexType == Field.Index.None)
                    {
                        if (!_DBProvider.Table.HasMirrorTable)
                        {
                            continue;
                        }
                    }
    
                    string value = null;
    
                    object v = DBNull.Value;
                    try
                    {
                        if (row.Table.Columns.Contains(field.Name))  //此处判断是否拥有该字段
                        {
                            v = row[field.Name];
                            
                        } 
                    }
                    catch (Exception ex)
                    {
    
                        Global.Report.WriteErrorLog(string.Format("this is a null value, collum {0} not in the table",field.Name));
                    }
    
    
                    if (v == DBNull.Value)
                    {
                        if (!field.CanNull)
                        {
                            throw new DataException(string.Format("Field:{0} in table {1} is not null so that it can't be inserted null value!",
                                field.Name, _DBProvider.Table.Name));
                        }
    
                        if (field.DefaultValue == null)
                        {
                            if (field.IndexType != Field.Index.None)
                            {
                                throw new DataException(string.Format("Field:{0} in table {1} is null but hasn't default value so that it can't be inserted null value!",
                                    field.Name, _DBProvider.Table.Name));
                            }
                        }
    
                        value = field.DefaultValue;
                    }
                    else
                    {
                        if (v is DateTime)
                        {
                            value = ((DateTime)v).ToString("yyyy-MM-dd HH:mm:ss.fff");
                        }
                        else
                        {
                            value = v.ToString();
                        }
                    }
    
                    document.Add(field.Name, value, field.DataType, field.DataLength, false);
                }

         这个问题成功解决。

      另外的问题如下:

    LogTime:2015-01-06 17:52:34.389
    Process:HubbleTask
    Message:System.ArgumentException: 输入字符串的格式不正确。不能在 JournalName 列中存储 <research in microelectronics and electronics, 2005 phd>。所需类型是 Double。 ---> System.FormatException: 输入字符串的格式不正确。
       在 System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
       在 System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
       在 System.Double.Parse(String s, NumberStyles style, NumberFormatInfo info)
       在 System.String.System.IConvertible.ToDouble(IFormatProvider provider)
       在 System.Data.Common.DoubleStorage.Set(Int32 record, Object value)
       在 System.Data.DataColumn.set_Item(Int32 record, Object value)
       --- 内部异常堆栈跟踪的结尾 ---
       在 System.Data.DataColumn.set_Item(Int32 record, Object value)
       在 System.Data.DataRow.set_Item(DataColumn column, Object value)
       在 Hubble.Core.DBAdapter.MongoAdapter.QuerySql(String sql) 位置 d:CodeOpenSourcehubbledotnet-100319C#srcHubble.DataHubble.CoreDBAdapterMongoAdapter.cs:行号 1081

        明明我在JournalName 存储的是一个NVarchar字段,此处却一定要提示我所需类型是double,系统脑抽么,这也是MongoAdapter的映射没做好,好在这种情况在整个数据集中出现的次数很少,我加上Try-Catch,输出了Log日志,解决了这个问题(O(∩_∩)O~)。

      以上两个问题解决之后,搜索引擎可以正确检索全部数据了,好开心。

      好水的文章,能解决别人的问题也是好的,虽然解决方法没那么优雅,而且Hubble现在还有人用么?默默的匿了。

  • 相关阅读:
    QT编译时 cc1plus进程占用大量内存卡死问题解决
    python import cv2 出错:cv2.x86_64-linux-gnu.so: undefined symbol
    python ImportError: No module named builtins
    OSError: libcudart.so.7.5: cannot open shared object file: No such file or directory
    二维数组和二级指针(转)
    C/C++中无条件花括号的妙用
    C语言中do...while(0)的妙用(转载)
    卸载 ibus 使Ubuntu16.04任务栏与启动器消失 问题解决
    关于Qt creator 无法使用fcitx输入中文的问题折腾
    QT error: cannot find -lGL
  • 原文地址:https://www.cnblogs.com/buptzym/p/4209903.html
Copyright © 2011-2022 走看看