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

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

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

  系统日志记录如下:

LogTime:-- ::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:\Codes\C#\OpenSources\hubbledotnet-\C#\src\Hubble.Data\Hubble.Core\Service\SynchronizeCanUpdate.cs:行号
在 Hubble.Core.Service.SynchronizeCanUpdate.GetDocumentsForInsert(IDBAdapter dbAdapter, Int64& from) 位置 d:\Codes\C#\OpenSources\hubbledotnet-\C#\src\Hubble.Data\Hubble.Core\Service\SynchronizeCanUpdate.cs:行号
在 Hubble.Core.Service.SynchronizeCanUpdate.DoGetDocumentsForInsertAsync(Object dbAdapter) 位置 d:\Codes\C#\OpenSources\hubbledotnet-\C#\src\Hubble.Data\Hubble.Core\Service\SynchronizeCanUpdate.cs:行号

找到对应的源代码,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:-- ::34.389
Process:HubbleTask
Message:System.ArgumentException: 输入字符串的格式不正确。不能在 JournalName 列中存储 <research in microelectronics and electronics, 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:\Code\OpenSource\hubbledotnet-\C#\src\Hubble.Data\Hubble.Core\DBAdapter\MongoAdapter.cs:行号

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

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

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

解决HubbleDotNet搜索引擎索引数据不全的问题的更多相关文章

  1. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[1]

    转载:http://quweiprotoss.wap.blog.163.com/ Push data to Solr or have Solr pull it 尽管一个应用通过HTTP方式与Solr通 ...

  2. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[1] (转)

    Index Data Author: David Smiley Eric Pugh 译者:Koala++ / 屈伟 在这一章中我们将了解如何将数据传入Solr.这个传入的过程称之为索引,尽管中间还包含 ...

  3. ES 18 - (底层原理) Elasticsearch写入索引数据的过程 以及优化写入过程

    目录 1 Lucene操作document的流程 1.1 添加document的流程 1.2 删除document的流程 2 优化写入流程 - 实现近实时搜索 2.1 流程的改进思路 2.2 设置re ...

  4. 数据库索引&数据页

    索引的好处 索引带来的益处可能很多读者会认为只是"能够提高数据检索的效率,降低数据库的IO成本". 确实,在数据库中表的某个字段创建索引,所带来的最大益处就是将该字段作为检索条件时 ...

  5. 使用NEWSEQUENTIALID解决GUID聚集索引问题

    原文:使用NEWSEQUENTIALID解决GUID聚集索引问题 UNIQUEIDENTIFIER做主键(Primary Key)是一件很方便的事情,在数据合并等操作中有不可替代的优势 但是由于普通的 ...

  6. 【solr】SolrCloud中索引数据存储于HDFS

    SolrCloud中索引数据存储于HDFS 本人最近使用SolrCloud存储索引日志条件,便于快速索引,因为我的索引条件较多,每天日志记录较大,索引想到将日志存入到HDFS中,下面就说说怎么讲sol ...

  7. geotrellis使用(十六)使用缓冲区分析的方式解决投影变换中边缘数据值计算的问题

    Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html 目录 前言 问题探索 采样说明 实现方案 总结 一.前言     ...

  8. 解决SQLSERVER在还原数据时出现的“FILESTREAM功能被禁用”问题

    解决SQLSERVER在还原数据时出现的“FILESTREAM功能被禁用”问题 今天由于测试需要,在网上下载了Adventureworks2008实例数据库的BAK文件,进行还原时出现了这样的错误“F ...

  9. [solr] - 索引数据删除

    删除solr索引数据,使用XML有两种写法: 1) <delete><id>1</id></delete> <commit/> 2) < ...

随机推荐

  1. Docker学习笔记第一章:补充

    只记得学习后面的命令,忘记整理一些概念性的东西了,只能做个补充了=.= Docker虽然也是一种虚拟技术,但是不同于虚拟机的概念.Docker是一种以容器为主的技术,容器运行不需要模拟层(emulat ...

  2. Java技术体系图

    Java程序员高级特性              反射.泛型.注释符.自动装箱和拆箱.枚举类.可变              参数.可变返回类型.增强循环.静态导入        核心编程       ...

  3. Python yield函数理解

    Python中的yield函数的作用就相当于一个挂起,是不被写入内存的,相当于一个挂起的状态,用的时候迭代,不用的时候就是一个挂起状态,挂起状态会以生成器的状态表现

  4. pythonchallenge 解谜 Level 4

    下一关... 一张图片,于是就点击了一下. 跳转到了 http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=12345 显示的是: ...

  5. Hibernate4 实例

    一.hibernate需要的配置文件 首先hibernate中有两种xml文件. .cfg,xml文件负责配置连接数据库的信息.指定映射类.指定hbm映射文件. .hbm.xml文件负责配置持久化类和 ...

  6. OHSCE_V0.1.22 Beta,跨平台高可靠性通信框架

    Open HI-REL Signal Communication Engine(简称OHSCE)是一款高可靠性跨平台的PHP通信框架,Windows友好且同时支持Linux和OS X.对TCP.UDP ...

  7. 工作总结_js倒计时

    最近在弄一个倒计时抽奖的项目,由于是每天的某个时间段所以,网上也没有找到自己合适的.就自己写了一个留下来以供参考.其中最值得注意的一点是不同种类型的手机对自定义的时间支持方式是不一样的.苹果时间只能支 ...

  8. TCP三次握手四次挥手

    看到一篇总结很好的TCP三次握手,学习一下,原文链接. 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,S ...

  9. 一图搞定【实战Java高并发程序设计】

    来了解下java并发的技术点吧.这里面包括了并发级别.算法.定律,还有开发包.在过去单核CPU时代,单任务在一个时间点只能执行单一程序,随着多核CPU的发展,并行程序开发就显得尤为重要.这本书主要介绍 ...

  10. quick-cocos2d-x 2.2.3 rc版本中 crypto.md5file() 的C++实现在ANDROID上有BUG

    原来的版本是用fopen打开文件的,如果要从ANDROID的APK中取文件,直接就洗白了修改如下 void CCCrypto::MD5File(const char* path, unsigned c ...