
    /// <summary>
    /// 全局公用的单Item数据包
    /// </summary>
    [ElasticsearchType(Name = "items")]
    public class Item
    {
        #region 抓取任务数据

        /// <summary>
        /// 抓取任务ID（只保留第一个抓取任务）
        /// </summary>
        /// <remarks>如果另一个Crawl抓取到此Item，会根据后者的设置修改Item属性，但不修改CrawlID</remarks>
        public string CrawlID { get; set; }

        /// <summary>
        /// 完成抓取的爬虫（只保留第一个）
        /// </summary>
        public string Crawler { get; set; }

        /// <summary>
        /// 抓取时间（第一次，如更新则修改UpdateTime）
        /// </summary>
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime FetchTime { get; set; }

        /// <summary>
        /// 该条目信息本系统最后更新的时间
        /// </summary>
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime UpdateTime { get; set; }

        /// <summary>
        /// 该条目信息的存储时间，用于分析分析效率与计算抓取质量
        /// </summary>
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime IndexTime { get; set; }

        ///<summary>
        /// 内容详细程度
        ///</summary>
        public Enums.ContentDetailLevel ContentDetailLevel { get; set; }

        #endregion 抓取任务数据

        #region 基础数据

        /// <summary>
        /// 文章ID
        /// </summary>
        public string ItemID { get; set; }

        /// <summary>
        /// 客户系统或对方网站的ItemID
        /// </summary>
        public string ClientItemID { get; set; }

        /// <summary>
        /// 父级ItemID
        /// </summary>
        public string ParentItemID { get; set; }

        /// <summary>
        /// 文章Url
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// 标题
        /// </summary>
        public string CleanTitle { get; set; }
        /// <summary>
        /// 短标题
        /// </summary>
        public string ShortTitle { get; set; }

        /// <summary>
        /// 正文
        /// </summary>
        public string CleanText { get; set; }

        /// <summary>
        /// HTML正文（如需要）
        /// </summary>
        public string HTMLText { get; set; }

        /// <summary>
        /// 摘要
        /// </summary>
        public string Summary { get; set; }

        /// <summary>
        /// 页面显示发布时间
        /// </summary>
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime PubDate { get; set; }

        /// <summary>
        /// PostIP
        /// </summary>
        public Int32 IP { get; set; }

        /// <summary>
        /// 作者或内容的地点属性
        /// </summary>
        public string Location { get; set; }

        /// <summary>
        /// Location集合的ID,外部的(如点评)设为Url
        /// </summary>
        public string PoID { get; set; }

        /// <summary>
        /// LocationID的来源,_前缀表示url未解开，Location集合中没有
        /// </summary>
        public string PoIDSource { get; set; }

        /// <summary>
        /// 接近某CBD的PoID
        /// </summary>
        public string NearCBD_PoID { get; set; }

        /// <summary>
        /// 纬度
        /// </summary>
        public float Lat { get; set; }

        /// <summary>
        /// 经度
        /// </summary>
        public float Lon { get; set; }

        /// <summary>
        /// 作者名（分词索引）
        /// </summary>
        public string AuthorName { get; set; }

        /// <summary>
        /// 作者ID
        /// </summary>
        public string AuthorID { get; set; }

        /// <summary>
        /// 作者图片
        /// </summary>
        public string AuthorImg { get; set; }

        /// <summary>
        /// 实名认证状态
        /// </summary>
        public Enums.CertificatedType AuthorCertificated { get; set; }

        /// <summary>
        /// Author.Tag字段，用于区分人
        /// </summary>
        public string AuthorTag { get; set; }

        /// <summary>
        /// 显示来源(比如使用终端等)
        /// </summary>
        public string Source { get; set; }

        /// <summary>
        /// 附带图片
        /// </summary>
        public string AttachImg { get; set; }

        /// <summary>
        /// 附带的外部链接
        /// </summary>
        public string AttachUrl { get; set; }

        /// <summary>
        /// 附件
        /// </summary>
        public string AttachFile { get; set; }

        #endregion
        //转载的ID,如果有的话
        public string RetweetID { get; set; }
        #region 媒体信息

        /// <summary>
        /// 媒体编号ID
        /// </summary>
        public string MediaID { get; set; }

        /// <summary>
        /// 媒体名称（分词索引）
        /// </summary>
        public string MediaName { get; set; }

        /// <summary>
        /// 频道/版面
        /// </summary>
        public string MediaChannel { get; set; }

        /// <summary>
        /// 在媒体中的排序，用以表示顺序或者重要性(例如头版、首页之类)
        /// </summary>
        public int Rank { get; set; }

        /// <summary>
        /// 媒体类型（网站|论坛|博客……）
        /// </summary>
        public Enums.MediaType MediaType { get; set; }

        /// <summary>
        /// 媒体发行范围（全国|地方|海外）
        /// </summary>
        public Enums.MediaRegionType MediaRegionType { get; set; }

        /// <summary>
        /// 媒体权重，主流媒体等
        /// </summary>
        public SByte MediaWeight { get; set; }

        /// <summary>
        /// 媒体性质（党报|市场化）
        /// </summary>
        public Enums.MediaOrganType MediaOrganType { get; set; }

        /// <summary>
        /// 语体类型（新闻|评论|转发……）
        /// </summary>
        public Enums.MediaStyle MediaStyle { get; set; }

        /// <summary>
        /// 政治倾向性（-3反动 -2极左 -1左倾 0中立 1右倾 2极右 3极端右）
        /// </summary>
        public SByte MediaTendency { get; set; }

        /// <summary>
        /// 媒体行业属性
        /// </summary>
        public string MediaIndustryIDs { get; set; }

        /// <summary>
        /// Media.MediaTag用于区分媒体集合
        /// </summary>
        public string MediaTag { get; set; }

        /// <summary>
        /// 代理分区 >0表示要翻墙
        /// </summary>
        public SByte ProxyZone { get; set; }

        /// <summary>
        /// 原始媒体ID（如果在媒体库中找到匹配）
        /// </summary>
        public string ReproducedMediaID { get; set; }

        /// <summary>
        /// 原始媒体名称
        /// </summary>
        public string ReproducedMediaName { get; set; }

        /// <summary>
        /// 原始媒体的Url
        /// </summary>
        public string ReproducedUrl { get; set; }
        /// <summary>
        /// 该媒体版权；0 未知，11 黑名单，12 无版权，13 不允许转载，14 拒绝抓取，20 白名单，21 采购可转授，22 自编，23 开放可商业转载，31 采购需单独授权，32 用户自有版权，33 用户自行承担版权，41 非商业使用
        /// </summary>
        public short MediaCopyright { get; set; }
        #endregion 媒体信息

        #region Item跟踪

        /// <summary>
        /// 跟踪设置和信息(评论)
        /// </summary>
        public ItemTracking Tracking { get; set; }

        /// <summary>
        /// 跟踪设置和信息（转发）
        /// </summary>
        public ItemTracking Tracking_Forward { get; set; }

        /// <summary>
        /// 最新的点击数、评论数、转发数
        /// </summary>
        public ItemCountData CurrentCount { get; set; }

        /// <summary>
        /// 定时获取的点击数、评论数、转发数（存ES）
        /// </summary>
        public ItemCountData[] CountHistory { get; set; }

        /// <summary>
        /// 回复数据
        /// </summary>
        public ItemReply[] Reply { get; set; }

        #endregion Item跟踪

        #region 扩展数据

        /// <summary>
        /// 相似转载ID（早先入库的相似文章ID，第一篇该字段为空，其他均为第一篇的ID）
        /// </summary>
        public string DuplicationID { get; set; }

        /// <summary>
        /// 分词结果
        /// </summary>
        public string SpliteTitle { get; set; }

        /// <summary>
        /// 分词结果
        /// </summary>
        public string SpliteText { get; set; }

        /// <summary>
        /// 是否进行过转载分析
        /// </summary>
        public bool ProsdDuplication { get; set; }

        /// <summary>
        /// 通用标签，根据各实体库中的Tag字段设置
        /// </summary>
        public string Tag { get; set; }

        /// <summary>
        ///  研报
        /// </summary>
        public ResearchReport ResearchReport { get; set; }

        ///<summary>
        ///分析字段，每个客户一条记录(支持不同的分析模型)
        ///</summary>
        [Nested(IncludeInParent = true)]//(Path = "analyzeData")]
        public ItemAnalyzeData[] AnalyzeData { get; set; }

        /// <summary>
        /// 管理字段，每个客户一条记录(支持不同的应用模型)
        /// </summary>
        [Nested(IncludeInParent = true)]//(Path = "manageData")]        
        public ItemManageData[] ManageData { get; set; }

        /// <summary>
        /// 发布字段，每个客户一条记录(支持不同的发布网站)
        /// </summary>
        [Nested(IncludeInParent = true)]//(Path = "publishData")]
        public ItemPublishData[] PublishData { get; set; }

        /// <summary>
        /// 语料标注字段，每个客户一条记录(支持不同的标注标准)
        /// </summary>
        [Nested(IncludeInParent = true)]//(Path = "labelData")]
        public ItemLabelData[] LabelData { get; set; }

        /// <summary>
        /// 提及（@）的用户（不含转发的@）
        /// </summary>
        public string[] ReferredAuthorIDs { get; set; }

        ///<summary>
        /// 原文是否已被删除
        ///</summary>
        public bool IsOriginalDeleted { get; set; }

        /// <summary>
        /// 是否是epr公司发布的软广
        /// </summary>
        public bool IsEPRPublished { get; set; }

        #endregion

        #region 文本结构化信息
        /// <summary>
        /// 文本结构化信息
        /// </summary>
        public Structured Struct { get; set; }
        #endregion

        #region Debug

        public override string ToString()
        {
            return string.Format("[ItemID:{0} Url:{1}]", ItemID, Url);
        }

        #endregion

        #region 智又盈扩展 废弃
        //public ZyyicItem ZyyicItem { get; set; }
        #endregion


        #region 扩展方法
        public string GetDisplayTitle(string issueID)
        {
            if (ManageData == null)
                return CleanTitle;

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                return CleanTitle;
            }
            else
            {
                if (string.IsNullOrEmpty(corrData.EditorTitle))
                    return CleanTitle;
                else
                    return corrData.EditorTitle;
            }
        }

        public string GetDisplayText(string issueID)
        {
            if (ManageData == null)
                return HTMLText;

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                return HTMLText;
            }
            else
            {

                if (string.IsNullOrEmpty(corrData.EditorText))
                    return HTMLText;
                else
                    return corrData.EditorText;
            }
        }

        public string GetDisplaySummary(string issueID)
        {
            if (ManageData == null)
                return "";

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID && data.ZyyicItemData!=null);
            if (corrData == null)
            {
                return "";
            }
            else
            {
                return corrData.ZyyicItemData.Summary;
            }
        }

        public ItemManageData GetItemManageData(string issueID)
        {
            if (ManageData == null)
                return null;

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                return null;
            }
            else
            {
                return corrData;
            }
        }

        public ItemAnalyzeData GetItemAnalyzeData(string issueID)
        {
            if (AnalyzeData == null)
                return null;

            var corrData = AnalyzeData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                return null;
            }
            else
            {
                return corrData;
            }
        }

        public void SetDisplayTitle(string issueID, string title)
        {
            if (ManageData == null)
                ManageData = new ItemManageData[] { new ItemManageData(issueID) };

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                var manageList = ManageData.ToList();
                manageList.Add(new ItemManageData(issueID) { EditorTitle = title });
                ManageData = manageList.ToArray();
            }
            else
            {
                corrData.EditorTitle = title;
            }

            if (string.IsNullOrEmpty(title))
                CleanTitle=title;
        }

        public void SetDisplaySummary(string issueID, string summary)
        {
            if (ManageData == null)
                ManageData = new ItemManageData[] { new ItemManageData(issueID) };

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                var manageList = ManageData.ToList();
                manageList.Add(new ItemManageData(issueID) { ZyyicItemData= new ZyyicItemData(){ Summary=summary} });
                ManageData = manageList.ToArray();
            }
            else
            {
                if (corrData.ZyyicItemData != null)
                    corrData.ZyyicItemData.Summary = summary;
                else
                    corrData.ZyyicItemData = new ZyyicItemData() { Summary = summary };
            }
        }

        public void SetDisplayText(string issueID, string text)
        {
            if (ManageData == null)
                ManageData = new ItemManageData[] { new ItemManageData(issueID) };

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                var manageList = ManageData.ToList();
                manageList.Add(new ItemManageData(issueID) { EditorText = text });
                ManageData = manageList.ToArray();
            }
            else
            {
                corrData.EditorText = text;
            }

            if (string.IsNullOrEmpty(HTMLText))
                HTMLText = text;
        }

        /// <summary>
        /// 设置删除标志
        /// </summary>
        /// <param name="issueID"></param>
        /// <param name="IsDeleted"></param>
        public void SetItemDeleted(string issueID, bool IsDeleted)
        {
            if (ManageData == null)
                ManageData = new ItemManageData[] { new ItemManageData(issueID) };

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                var manageList = ManageData.ToList();
                manageList.Add(new ItemManageData(issueID) { IsDeleted = IsDeleted });
                ManageData = manageList.ToArray();
            }
            else
            {
                corrData.IsDeleted = IsDeleted;
            }
        }
        #endregion

         /// <summary>
        /// 设置审核标志
        /// </summary>
        /// <param name="issueID"></param>
        /// <param name="IsDeleted"></param>
        public void SetItemStatus(string issueID,Enums.ZyyicEnums.Status status)
        {
            if (ManageData == null)
                ManageData = new ItemManageData[] { new ItemManageData(issueID) };

            var corrData = ManageData.FirstOrDefault(data => data.IssueID == issueID);
            if (corrData == null)
            {
                var manageList = ManageData.ToList();
                manageList.Add(new ItemManageData(issueID) { HandleStatus = (sbyte)status });
                ManageData = manageList.ToArray();
            }
            else
            {
                corrData.HandleStatus = (sbyte)status;
            }
        }
    }

    /// <summary>
    /// 抓取下来的原始数据（供Crawler传递给后端）
    /// </summary>
    [Serializable]
    public class RawItem
    {
        #region 抓取任务数据

        /// <summary>
        /// 抓取任务ID（只保留第一个抓取任务）
        /// </summary>
        /// <remarks>如果另一个Crawl抓取到此Item，会根据后者的设置修改Item属性，但不修改CrawlID</remarks>
        public string CrawlID { get; set; }

        /// <summary>
        /// 完成抓取的爬虫（只保留第一个）
        /// </summary>
        public string Crawler { get; set; }

        /// <summary>
        /// 抓取时间（第一次，如更新则修改UpdateTime）
        /// </summary>
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime FetchTime { get; set; }

        ///<summary>
        /// 内容详细程度
        ///</summary>
        public Enums.ContentDetailLevel ContentDetailLevel { get; set; }

        #endregion 抓取任务数据

        #region 基础数据

        /// <summary>
        /// 文章ID
        /// </summary>
        public string ItemID { get; set; }

        /// <summary>
        /// 客户系统或对方网站的ItemID
        /// </summary>
        public string ClientItemID { get; set; }

        /// <summary>
        /// 父级ItemID
        /// </summary>
        public string ParentItemID { get; set; }

        /// <summary>
        /// 文章Url
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// 标题
        /// </summary>
        public string CleanTitle { get; set; }

        /// <summary>
        /// 正文
        /// </summary>
        public string CleanText { get; set; }

        /// <summary>
        /// HTML正文（如需要）
        /// </summary>
        public string HTMLText { get; set; }

        /// <summary>
        /// 页面显示发布时间
        /// </summary>
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime PubDate { get; set; }

        /// <summary>
        /// IP
        /// </summary>
        public Int32 IP { get; set; }

        /// <summary>
        /// 作者或内容的地点属性
        /// </summary>
        public string Location { get; set; }

        /// <summary>
        /// Location集合的ID,外部的(如点评)设为Url
        /// </summary>
        public string PoID { get; set; }

        /// <summary>
        /// LocationID的来源,_前缀表示url未解开，Location集合中没有
        /// </summary>
        public string PoIDSource { get; set; }

        /// <summary>
        /// 纬度
        /// </summary>
        public float Lat { get; set; }

        /// <summary>
        /// 经度
        /// </summary>
        public float Lon { get; set; }

        /// <summary>
        /// 作者名（分词索引）
        /// </summary>
        public string AuthorName { get; set; }

        /// <summary>
        /// 作者ID
        /// </summary>
        public string AuthorID { get; set; }

        /// <summary>
        /// 作者图片
        /// </summary>
        public string AuthorImg { get; set; }

        /// <summary>
        /// 实名认证状态
        /// </summary>
        public Enums.CertificatedType AuthorCertificated { get; set; }

        /// <summary>
        /// 显示来源(比如使用终端等)
        /// </summary>
        public string Source { get; set; }

        /// <summary>
        /// 附带图片
        /// </summary>
        public string AttachImg { get; set; }

        /// <summary>
        /// 附带的外部链接
        /// </summary>
        public string AttachUrl { get; set; }

        /// <summary>
        /// 附件
        /// </summary>
        public string AttachFile { get; set; }

        /// <summary>
        /// 在媒体中的排序，用以表示顺序或者重要性(例如头版、首页之类)
        /// </summary>
        public int Rank { get; set; }

        #endregion

        #region 媒体信息

        /// <summary>
        /// 页面显示原始媒体名称
        /// </summary>
        public string ReproducedMediaName { get; set; }

        /// <summary>
        /// 页面显示原始媒体的Url
        /// </summary>
        public string ReproducedUrl { get; set; }

        #endregion 媒体信息

        public RawItem()
        {

        }
        public RawItem(string CrawlID, string Crawler, Enums.ContentDetailLevel DetailLevel)
        {
            this.CrawlID = CrawlID;
            this.Crawler = Crawler;
            this.ContentDetailLevel = DetailLevel;
            FetchTime = DateTime.Now;
        }

        public RawItem(string CrawlID, string Crawler, Enums.ContentDetailLevel DetailLevel, string Url)
        {
            this.CrawlID = CrawlID;
            this.Crawler = Crawler;
            this.ContentDetailLevel = DetailLevel;
            this.Url = Url;
            this.ItemID = MD5Helper.getMd5Hash(Url);
            FetchTime = DateTime.Now;
        }
    }

    /// <summary>
    /// 属性评分结果的数据结构
    /// </summary>
    public class AttributeEvaluationResult
    {
        /// <summary>
        /// 属性名称
        /// </summary>
        public string Attribute { get; set; }

        /// <summary>
        /// 该属性的得分
        /// </summary>
        public float Value { get; set; }

        /// <summary>
        /// 命中该属性的词
        /// </summary>
        public string[] MatchedWords { get; set; }
        public AttributeEvaluationResult(string Attribute, float Value, string[] MatchedWords)
        {
            this.Attribute = Attribute;
            this.Value = Value;
            this.MatchedWords = MatchedWords;
        }
    }


    /// <summary>
    /// 语料标注属性
    /// </summary>
    [Serializable]
    public class ItemLabelData
    {
        /// <summary>
        /// 议题编号
        /// </summary>
        public string IssueID { get; set; }
        public ItemLabelData()
        {

        }
        //todo:语料标注工具设计
    }
