人臉比對動態庫操作

頭文件


/** @file  mongodb.h
*  @note   HangZhou Hikvision System Technology Co., Ltd. All Right Reserved.
*  @brief  Start the server entrance
*  @author Juzheng([email protected])
*  @date   2018/5/2
*  @note   v1.0.0 Created
*  @history
*  @warning
*/
#pragma once

#include "mongodb.h"
#include "structDataUnit.h"
#include "GlobalRes.h"

#define 	DYNAMIC_HUMAN_DB_NAME    	"face"
#define 	DYNAMIC_HUMAN_COLL_NAME		"Dynamic_human"
#define     DYNAMIC_HUMAN_CACHE_SIZE     5000
const HPR_INT64	DY_PARTION_COUNT =           300; 

typedef struct DY_CACHE_OP_
{
	VEC_DOCUMENTS 		bathInsertDocuments;	//緩存數據
	HPR_Mutex      	 	xLock; 					//線程同步鎖
	HPR_TIME_T 			version;				//版本號
	THREAD_TASK_COPY_T  vecTaskCopy;         	//批量插入線程參數
}DY_CACHE_OP;

class CStructDynamicHuman
{
public:
	~CStructDynamicHuman(void);

	static CStructDynamicHuman& Instance();
	HPR_INT32 InitDynamicHuman(HPR_INT32 iMaxThreadNum);
	HPR_INT32 UninitDynamicHuman();
	HPR_BOOL StartDynamicHuman();
	HPR_VOID StopDynamicHuman();
	
	HPR_INT32 creatIndex(vector<string> &strIndexField, HPR_INT32 iSortType,  HPR_BOOL background, HPR_BOOL bUnique = HPR_FALSE);
	
	HPR_INT32 DynamicHumanBatchInsert(StructDynamicInfo& humanInfo, HPR_INT32 iThreadNum = 0);
	
	HPR_INT32  DynamicHumanFind(const StruDymFindCondition& condition, vector<StructDynamicInfo> & vecResult, StruDymSort &struSort);

	HPR_INT32  DynamicHumanModelFind(const StruDymFindCondition& condition, vector<StructHumanModelInfo> & vecResult, StruDymSort &struSort);

	HPR_INT32  DynamicHumanUpdate(const string& id, StructDynamicInfo& struHumanInfo);

	HPR_INT32  DynamicHumanDelete(const HPR_INT64& lDate);

	HPR_INT32 DynamicHumanTotalCount(const StruDymFindCondition& condition, HPR_INT32&  total);
	
	HPR_INT32 DynamicHumanDateCount(const StruDymFindCondition& condition, StruDymGroup struGroupType, vector<StruDateCountResult>& vecCountResult);
	
	HPR_INT32 DynamicHumanDistinct(string distinctName, const StruDymFindCondition& condition, vector<string> &vecResaults);
	
	HPR_INT32 DynamicHumanSplitData();
	
	HPR_VOID DynamicHumanGetSplitData(vector<HPR_INT64>&	vecSplitId);
	
	HPR_INT32 DynamicHumanAvageSize(HPR_INT32 &iAvageSize);
	
	HPR_INT32 SetDyHumanInfoHook(DyHumanInfoHook func);
	
	HPR_INT32 cache_bath_insert_task();
	
	HPR_VOID cache_bath_sub_insert_task(HPR_INT32 &iTaskIndex, HPR_SEM_T &semSync);
	
	HPR_TIME_T get_time();

private:
	//Not allow copy.
	CStructDynamicHuman();
	CStructDynamicHuman(const CStructDynamicHuman&);
	CStructDynamicHuman& operator=(const CStructDynamicHuman&);


	string m_dbName;												//數據庫
	string m_collName;												//集合
	HPR_INT32 					m_MaxThreadNum;			//最大線程數
	vector<DY_CACHE_OP>			m_vecBatchInsertOp;		//批量插入操作結構體
	HPR_BOOL          			m_bThreadExit;			//線程退出標誌
	DyHumanInfoHook       		m_DyHumanInfofunc;  	//根據版本號獲取數據回調函數
	HPR_Mutex               	m_timeLock;
	vector<HPR_INT64>           m_vecSplitId;			//動態庫數據切分點
	string						m_strLastData;				//最後一條數據ID
};


cpp 

#include "structDynamicHuman.h"


/*動態庫屬性表定義*/
#define DYNAMIC_HUMAN_TABLE_ID			"_id"					/*表ID,作爲主鍵使用*/
#define DYNAMIC_HUMAN_TRACE_UUID		"trace_uuid"			/*人唯一標識*/
#define DYNAMIC_HUMAN_TRACE_IDX			"trace_id"				/*屬於此人的圖片唯一標識*/
#define DYNAMIC_HUMAN_SNAP_TIME         "snap_time"				/*抓拍時間*/
#define DYNAMIC_HUMAN_DEVICE_ID			"device_id"				/*設備ID,作爲主鍵使用*/
#define DYNAMIC_HUMAN_DEVICE_TYPE		"device_type"			/*設備ID,作爲主鍵使用*/
#define DYNAMIC_HUMAN_INDEX				"index"					/*預分類值*/
#define DYNAMIC_HUMAN_GLASS				"glass"					/*戴眼鏡*/
#define DYNAMIC_HUMAN_GENDER			"gender"				/*性別*/
#define DYNAMIC_HUMAN_AGE				"age_range"				/*年齡段*/
#define DYNAMIC_HUMAN_SMILE				"smile"					/*微笑*/
#define DYNAMIC_HUMAN_ETHNIC			"ethnic"				/*民族*/
#define DYNAMIC_HUMAN_RECT				"rect"					/*大圖座標框*/
#define DYNAMIC_HUMAN_FACE_RECT			"face_rect"				/*小圖座標框*/
#define DYNAMIC_HUMAN_POSE				"pose"					/*拍攝角度*/
#define DYNAMIC_HUMAN_BG_URL			"bg_url"				/*大圖URL*/
#define DYNAMIC_HUMAN_FACE_URL			"face_url"				/*小圖URL*/
#define DYNAMIC_HUMAN_ERR_CODE			"error_code"			/*錯誤碼*/
#define DYNAMIC_HUMAN_VERSION			"version"				/*版本號*/
#define DYNAMIC_HUMAN_MOD				"mod"					/*分片取模值*/
#define DYNAMIC_HUMAN_MODEL_DATA		"model"					/*模型數據*/
#define DYNAMIC_HUMAN_DETECT_QUALITY    "detect_quality"		/*人臉框類型*/
#define DYNAMIC_HUMAN_POINTS_QUALITY    "points_quality"		/*特徵點置信度*/
#define DYNAMIC_HUMAN_EYE_DISTANCE	    "eye_distance"			/*瞳距*/
#define DYNAMIC_HUMAN_COLOR_CONF		"color_conf"			/*彩色置信度*/
#define DYNAMIC_HUMAN_GRAY_SCALE		"gray_scale"			/*灰階度*/
#define DYNAMIC_HUMAN_GRAY_MEAN		    "gray_mean"				/*灰度均值*/
#define DYNAMIC_HUMAN_GRAY_VAR		    "gray_var"				/*灰度均方差*/
#define DYNAMIC_HUMAN_CLEARITY		    "clearity"				/*清晰度*/
#define DYNAMIC_HUMAN_POSE_PITCH		"pose_pitch"			/*俯仰角*/
#define DYNAMIC_HUMAN_POSE_YAW		    "pose_yaw"				/*左右角*/
#define DYNAMIC_HUMAN_POSE_ROLL		    "pose_roll"				/*平面內旋轉角*/
#define DYNAMIC_HUMAN_POSE_CONF		    "pose_conf"				/*姿態置信度*/
#define DYNAMIC_HUMAN_FRONTAL		    "frontal"				/*正面評分*/
#define DYNAMIC_HUMAN_VISIBLE_QUALITY	"visible_quality"		/*可見性評分*/
#define DYNAMIC_HUMAN_TOTAL_QUALITY		"total_quality"			/*人臉總評分*/

#define DYNAMIC_HUMAN_LIB_ID			"lib_id"				/*打標籤以後,對應靜態庫的庫ID*/
#define DYNAMIC_HUMAN_HUMAN_ID			"human_id"				/*打標籤以後,對應靜態庫的人員ID*/
#define DYNAMIC_HUMAN_IS_LABELED		"is_labeled"			/*是否已打標籤(0-未打標籤, 1-已打標籤)*/

#define DYNAMIC_DEVICE_TABLE_ID			"_id"					/*設備ID,作爲主鍵使用,與device_id關聯*/
#define DYNAMIC_DEVICE_TYPE				"device_type"			/*設備類型*/
#define DYNAMIC_DEVICE_NAME				"device_name"			/*設備名稱*/
#define DYNAMIC_DEVICE_LNG				"deviceLongitude"		/*經度*/
#define DYNAMIC_DEVICE_LAT				"deviceLatitude"		/*緯度*/


static HPR_VOID* CALLBACK Dynamic_human_sub_insert_thread(HPR_VOID* param)
{
	if(NULL != param)
	{
		HPR_INT32 iThreadIndex = 0;
		HPR_INT32 iTaskId = 0;
		THREAD_TASK_COPY_T *pCopy = (THREAD_TASK_COPY_T *)param;
		CStructDynamicHuman *pDataCache = (CStructDynamicHuman*)pCopy->pThis;
		iThreadIndex = pCopy->nIndex;
		iTaskId = pCopy->nTaskId;
		pDataCache->cache_bath_sub_insert_task(iTaskId, pCopy->semSync);
		CGlobalRes::Instance().PushThreadID(iThreadIndex);
	}
    return NULL;
}

/** @fn  CStructDynamicHuman::CStructDynamicHuman()
*  @brief CStructDynamicHuman
*  @param void
*  @return 
*/
CStructDynamicHuman::CStructDynamicHuman()
:m_dbName(DYNAMIC_HUMAN_DB_NAME)
,m_collName(DYNAMIC_HUMAN_COLL_NAME)
,m_bThreadExit(HPR_FALSE)
,m_DyHumanInfofunc(NULL)
{

}

/** @fn  CStructDynamicHuman::~CStructDynamicHuman()
*  @brief CStructDynamicHuman
*  @param void
*  @return 
*/
 CStructDynamicHuman::~CStructDynamicHuman()
{
 
}

 
/**@fn 	 InitDynamicHuman
* @brief	  初始化動態庫
* @param	 iMaxThreadNum		 [in]	 - 最大線程數
* @return  錯誤碼: 成功 DB_SUCCESS
* @note	
*/
HPR_INT32 CStructDynamicHuman::InitDynamicHuman(HPR_INT32 iMaxThreadNum)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	try	
	{
		/*初始化緩存隊列大小*/
		m_MaxThreadNum = iMaxThreadNum;
		m_vecBatchInsertOp.resize(m_MaxThreadNum);	

		/*創建index*/
		vector<string> vecIndexField;
		vecIndexField.push_back(DYNAMIC_HUMAN_VERSION);
		iRetVal = creatIndex(vecIndexField, 1, HPR_TRUE);
		if(LS_SERVER_OK != iRetVal)
		{
			STRU_ERROR("CStructDynamicHuman::creatIndex failed: 0x%x", iRetVal);
			return iRetVal;
		}

		vecIndexField.clear();
		vecIndexField.push_back(DYNAMIC_HUMAN_TRACE_UUID);
		vecIndexField.push_back(DYNAMIC_HUMAN_TRACE_IDX);
		iRetVal = creatIndex(vecIndexField, 1, HPR_TRUE, HPR_TRUE);
		if(LS_SERVER_OK != iRetVal)
		{
			STRU_ERROR("CStructDynamicHuman::creatIndex failed: 0x%x", iRetVal);
			return iRetVal;
		}
		
		vecIndexField.clear();
		vecIndexField.push_back(DYNAMIC_HUMAN_DEVICE_ID);
		vecIndexField.push_back(DYNAMIC_HUMAN_SNAP_TIME);
		iRetVal = creatIndex(vecIndexField, 1, HPR_TRUE);
		if(LS_SERVER_OK != iRetVal)
		{
			STRU_ERROR("CStructDynamicHuman::creatIndex failed: 0x%x", iRetVal);
			return iRetVal;
		}

		vecIndexField.clear();
		vecIndexField.push_back(DYNAMIC_HUMAN_SNAP_TIME);
		iRetVal = creatIndex(vecIndexField, 1, HPR_TRUE);
		if(LS_SERVER_OK != iRetVal)
		{
			STRU_ERROR("CStructDynamicHuman::creatIndex failed: 0x%x", iRetVal);
			return iRetVal;
		}

		vecIndexField.clear();
		vecIndexField.push_back(DYNAMIC_HUMAN_HUMAN_ID);
		iRetVal = creatIndex(vecIndexField, 1, HPR_TRUE);
		if(LS_SERVER_OK != iRetVal)
		{
			STRU_ERROR("CStructDynamicHuman::creatIndex failed: 0x%x", iRetVal);
			return iRetVal;
		}
		
		vecIndexField.clear();
		vecIndexField.push_back(DYNAMIC_HUMAN_MOD);
		iRetVal = creatIndex(vecIndexField, 1, HPR_TRUE);
		if(LS_SERVER_OK != iRetVal)
		{
			STRU_ERROR("CStructDynamicHuman::creatIndex failed: 0x%x", iRetVal);
			return iRetVal;
		}
		
		CStructDynamicHuman::Instance().StartDynamicHuman();
	}
	catch (const std::exception& xcp) 
	{
	 	STRU_ERROR("mongodb initial failed: %s", xcp.what());
		return LS_SERVER_DB_INIT_ERROR;
	}
	STRU_INFO("InitDynamicHuman success");
	return LS_SERVER_OK;
}

HPR_INT32 CStructDynamicHuman::UninitDynamicHuman()
{
	CStructDynamicHuman::Instance().StopDynamicHuman();
	return LS_SERVER_OK;
}

/**@fn      StartDynamicHuman
 * @brief    啓動動態庫類
 * @return  錯誤碼: 成功 HPR_TRUE
 * @note   
 */
HPR_BOOL CStructDynamicHuman::StartDynamicHuman()
{
	for(HPR_UINT32 i = 0; i < m_vecBatchInsertOp.size(); ++i)
	{
		m_vecBatchInsertOp[i].version = HPR_TimeNow();	
		HPR_SemCreate(&(m_vecBatchInsertOp[i].vecTaskCopy.semSync),0);
		HPR_SemCreate(&(m_vecBatchInsertOp[i].vecTaskCopy.semThreadExit),1);
		m_vecBatchInsertOp[i].vecTaskCopy.pThis = this;
	}
	return HPR_TRUE;
}

/**@fn      StopDynamicHuman
 * @brief    停止動態庫類
 * @return  HPR_VOID
 * @note   
 */
HPR_VOID CStructDynamicHuman::StopDynamicHuman()
{
	m_bThreadExit = HPR_TRUE;
	
	STRU_INFO("StopDynamicHuman ");
}

/**@fn      creatIndex
 * @brief    創建index
 * @param   strIndexField       [in]    - 索引字段
 * @param   iSortType     		[in]    - 索引正序或倒序
 * @param   bUnique     		[in]    - 是否唯一索引
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32 CStructDynamicHuman::creatIndex(vector<string> &strIndexField, HPR_INT32 iSortType, HPR_BOOL background, HPR_BOOL bUnique)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	
	bsoncxx::builder::stream::document index;
	
	do
	{
		stringstream streamindex;
		for(HPR_UINT32 i = 0; i < strIndexField.size(); i++)
		{
			index<< strIndexField[i]  << iSortType;
			streamindex<<strIndexField[i]<<"_";
		}
		streamindex<<"index";
		
		string strIndexName = streamindex.str();
		if(LS_SERVER_OK != MongoDB::Instance().check_index(m_dbName, m_collName, strIndexName))
		{
			iRetVal = MongoDB::Instance().creat_index(m_dbName, m_collName, index, bUnique, strIndexName, background);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructDynamicHuman::creat_index failed: 0x%x", iRetVal);
				break;
			}
			STRU_INFO("CStructDynamicHuman::creat_index [ %s ]", bsoncxx::to_json(index.view()).c_str());
		}
		iRetVal = LS_SERVER_OK;
	}while (0);
	
	return iRetVal;
}


/**@fn      Instance
 * @brief    動態庫單例模式
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
CStructDynamicHuman& CStructDynamicHuman::Instance()
{
	static CStructDynamicHuman DynamicHumanStor;
	return DynamicHumanStor;
}


/**@fn      DynamicHumanBatchInsert
 * @brief    動態庫批量插入
 * @param   humanInfo      [in]    - 插入人員信息
 * @param   iThreadNum     [in]    - 使用的線程編號
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32 CStructDynamicHuman::DynamicHumanBatchInsert(StructDynamicInfo& humanInfo, HPR_INT32 iThreadNum)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	do
	{
		try	
		{ 
			HPR_INT32 iThreadMod = iThreadNum % m_MaxThreadNum;
			while(m_vecBatchInsertOp[iThreadMod].bathInsertDocuments.size() > DYNAMIC_HUMAN_CACHE_SIZE)
			{
				STRU_DEBUG("insert too fast, cache[%ld] ", m_vecBatchInsertOp[iThreadMod].bathInsertDocuments.size()) ;
				HPR_Sleep(1000);
			}
			HPR_Guard stGuard0(&(m_vecBatchInsertOp[iThreadMod].xLock));
			HPR_TIME_T lVersion			    = m_vecBatchInsertOp[iThreadMod].version;
			auto builder = bsoncxx::builder::stream::document{};
			UPDATE_OPT UpdateOpt;
			UpdateOpt.document<< "$set" << open_document;
			UpdateOpt.document<< DYNAMIC_HUMAN_TRACE_UUID 		<< humanInfo.sztrace_uuid;
			UpdateOpt.document<< DYNAMIC_HUMAN_TRACE_IDX  		<< humanInfo.trace_idx;
		    UpdateOpt.document<< DYNAMIC_HUMAN_SNAP_TIME		<< bsoncxx::types::b_date{std::chrono::milliseconds{humanInfo.snap_time}};
			UpdateOpt.document<< DYNAMIC_HUMAN_DEVICE_ID 		<< humanInfo.strudevice_info.szdevice_id;
			UpdateOpt.document<< DYNAMIC_HUMAN_DEVICE_TYPE		<< humanInfo.strudevice_info.device_type;
			UpdateOpt.document<< DYNAMIC_DEVICE_NAME	    	<< humanInfo.strudevice_info.szdevice_name;
			UpdateOpt.document<< DYNAMIC_HUMAN_INDEX			<< humanInfo.index;
		    UpdateOpt.document<< DYNAMIC_HUMAN_GLASS 			<< humanInfo.glass;
		    UpdateOpt.document<< DYNAMIC_HUMAN_GENDER 			<< humanInfo.gender;
		    UpdateOpt.document<< DYNAMIC_HUMAN_AGE 				<< humanInfo.age_range;
		    UpdateOpt.document<< DYNAMIC_HUMAN_SMILE 			<< humanInfo.smile;
		    UpdateOpt.document<< DYNAMIC_HUMAN_ETHNIC 			<< humanInfo.ethnic;
		    UpdateOpt.document<< DYNAMIC_HUMAN_RECT 			<< humanInfo.szrect;
		    UpdateOpt.document<< DYNAMIC_HUMAN_FACE_RECT 		<< humanInfo.szface_rect;
		    UpdateOpt.document<< DYNAMIC_HUMAN_POSE 			<< humanInfo.szpose;
		    UpdateOpt.document<< DYNAMIC_HUMAN_BG_URL 			<< humanInfo.szbg_url;
		    UpdateOpt.document<< DYNAMIC_HUMAN_FACE_URL			<< humanInfo.szface_url;
		    UpdateOpt.document<< DYNAMIC_HUMAN_ERR_CODE   		<< humanInfo.error_code;
			UpdateOpt.document<< DYNAMIC_HUMAN_VERSION			<< lVersion;
		    UpdateOpt.document<< DYNAMIC_HUMAN_MOD				<< humanInfo.mod_id;
		    UpdateOpt.document<< DYNAMIC_HUMAN_LIB_ID			<< humanInfo.lib_id;
		    UpdateOpt.document<< DYNAMIC_HUMAN_HUMAN_ID   		<< humanInfo.human_id;
		    UpdateOpt.document<< DYNAMIC_HUMAN_IS_LABELED		<< humanInfo.is_labeled;
		    UpdateOpt.document<< DYNAMIC_HUMAN_MODEL_DATA 		<< humanInfo.model ;
			UpdateOpt.document<< DYNAMIC_HUMAN_DETECT_QUALITY	<< humanInfo.detect_quality;
			UpdateOpt.document<< DYNAMIC_HUMAN_POINTS_QUALITY	<< humanInfo.fPoints_quality;
			UpdateOpt.document<< DYNAMIC_HUMAN_EYE_DISTANCE  	<< humanInfo.fEye_distance;
			UpdateOpt.document<< DYNAMIC_HUMAN_COLOR_CONF    	<< humanInfo.fColor_conf;
			UpdateOpt.document<< DYNAMIC_HUMAN_GRAY_SCALE    	<< humanInfo.gray_scale;
			UpdateOpt.document<< DYNAMIC_HUMAN_GRAY_MEAN     	<< humanInfo.fGray_mean;
			UpdateOpt.document<< DYNAMIC_HUMAN_GRAY_VAR      	<< humanInfo.fGray_var;
			UpdateOpt.document<< DYNAMIC_HUMAN_CLEARITY      	<< humanInfo.fClearity;
			UpdateOpt.document<< DYNAMIC_HUMAN_POSE_PITCH    	<< humanInfo.fPose_pitch;
			UpdateOpt.document<< DYNAMIC_HUMAN_POSE_YAW	    	<< humanInfo.fPose_yaw;
			UpdateOpt.document<< DYNAMIC_HUMAN_POSE_ROLL     	<< humanInfo.fPose_roll;
			UpdateOpt.document<< DYNAMIC_HUMAN_POSE_CONF     	<< humanInfo.fPose_conf;
			UpdateOpt.document<< DYNAMIC_HUMAN_FRONTAL	    	<< humanInfo.fFrontal;
			UpdateOpt.document<< DYNAMIC_HUMAN_VISIBLE_QUALITY	<< humanInfo.fVisible_quality;
			UpdateOpt.document<< DYNAMIC_HUMAN_TOTAL_QUALITY 	<< humanInfo.fTotal_quality;
			UpdateOpt.document<< close_document;
									
			UpdateOpt.filter_builder<< DYNAMIC_HUMAN_TRACE_UUID << humanInfo.sztrace_uuid << DYNAMIC_HUMAN_TRACE_IDX << humanInfo.trace_idx;
			
			m_vecBatchInsertOp[iThreadMod].bathInsertDocuments.push_back(std::move(UpdateOpt)); 
			
			//STRU_DEBUG("CStructDynamicHuman::DynamicHumanBatchInsert [ %s ]", bsoncxx::to_json(doc_value.view()).c_str());
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructDynamicHuman::DynamicHumanBatchInsert failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}

/**@fn      DynamicHumanFind
 * @brief    動態庫查詢
 * @param   condition      [in]    - 過濾條件
 * @param   vecResult      [out]   - 查詢結果
 * @param   struSort       [in]    - 排序條件
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32  CStructDynamicHuman::DynamicHumanFind(const StruDymFindCondition& condition, vector<StructDynamicInfo> & vecResult, StruDymSort &struSort)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	std::vector<bsoncxx::document::value> results; 
	do
	{
		try	
		{
			bsoncxx::builder::stream::document filter_builder;
			
			/*{"_id" : { "$in" : ["xxx","ccc"] } }*/
			if(0 != condition.condition.ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.ids) 
				{
					bsoncxx::stdx::string_view strId = e;   //轉換成bsoncxx::stdx::string_view 是因爲mongo-cxx-driver源碼裏對b_oid類型的初始化有BUG,char*類型初始化不會成功
					child_builder<< bsoncxx::types::b_oid{bsoncxx::oid{strId}};
				}
				filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.human_ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.human_ids) 
				{
					child_builder<<e;
				}
				filter_builder << DYNAMIC_HUMAN_HUMAN_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.struDevice_info.vecDeviceIds.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.struDevice_info.vecDeviceIds) 
				{
					child_builder << e;
				}
				filter_builder << DYNAMIC_HUMAN_DEVICE_ID 	<< open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			
			if(condition.condition.struDevice_info.device_type != -1 )
				filter_builder << DYNAMIC_HUMAN_DEVICE_TYPE    << condition.condition.struDevice_info.device_type;
			if(condition.condition.glass != -1 )
				filter_builder << DYNAMIC_HUMAN_GLASS    	   << condition.condition.glass;
			if(condition.condition.gender != -1 )
				filter_builder << DYNAMIC_HUMAN_GENDER   	   << condition.condition.gender;
			if(condition.condition.age_range != -1)
				filter_builder << DYNAMIC_HUMAN_AGE  	 	   << condition.condition.age_range;
			if(condition.condition.smile != -1)
				filter_builder << DYNAMIC_HUMAN_SMILE          << condition.condition.smile;
			if(condition.condition.ethnic != -1 )
				filter_builder << DYNAMIC_HUMAN_ETHNIC         << condition.condition.ethnic;
			if( condition.condition.result_status != -1 )
				filter_builder << DYNAMIC_HUMAN_ERR_CODE       << condition.condition.result_status;
			if( condition.condition.version != -1 )
				filter_builder << DYNAMIC_HUMAN_VERSION        << condition.condition.version;
			if( condition.condition.mod_id != -1 )
				filter_builder << DYNAMIC_HUMAN_MOD            << condition.condition.mod_id;
			if(condition.condition.end_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$lte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.end_time}}<< close_document;
			if(condition.condition.begin_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$gte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.begin_time}}<< close_document;
			if(condition.skipId.size() != 0 )
			{
				bsoncxx::stdx::string_view strId = condition.skipId;
				if (-1 == struSort.iSortType)
				{
					filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document <<"$lt"<<bsoncxx::types::b_oid{bsoncxx::oid{strId}}<< close_document;
				}
				else if (1 == struSort.iSortType)
				{
					filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document <<"$gt"<<bsoncxx::types::b_oid{bsoncxx::oid{strId}}<< close_document;
				}
			}

			std::string strSort = "";
			if (-1 != struSort.iSortField)
			{
				if (0 == struSort.iSortField)
				{
					strSort = DYNAMIC_HUMAN_TABLE_ID;
				}
				else if (1 == struSort.iSortField)
				{
					strSort = DYNAMIC_HUMAN_SNAP_TIME;
				}
			}
			StruSearchOpt struOpt;
			struOpt.strSort 	= strSort;
			struOpt.iSortType 	= struSort.iSortType;
			struOpt.iLimit 		= condition.limit;
			if(condition.skipId.size() != 0)
			{
				struOpt.iskip = 0;
			}
			else
			{
				struOpt.iskip = condition.offset;
			}
			STRU_INFO("filter_builder find(%s).sort(%s:%d).limit(%d).offset(%d)", bsoncxx::to_json(filter_builder.view()).c_str(), 
										struOpt.strSort.c_str(), struOpt.iSortType, struOpt.iLimit, struOpt.iskip);

			iRetVal = MongoDB::Instance().search(m_dbName, m_collName, filter_builder, results, struOpt);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("MongoDB::search failed: 0x%x", iRetVal);
				break;
			}
			for (auto  &doc : results)
			{
				auto DymDocument 	= 	doc.view();
				
				StructDynamicInfo struOneRes;
				
  				memset(&struOneRes, 0, sizeof(StructDynamicInfo));
				if(DymDocument[DYNAMIC_HUMAN_TABLE_ID].length())
					HPR_Strncpy(struOneRes.sz_id, DymDocument[DYNAMIC_HUMAN_TABLE_ID].get_oid().value.to_string().c_str(), sizeof(struOneRes.sz_id));
				if(DymDocument[DYNAMIC_HUMAN_TRACE_UUID].length())
					HPR_Strncpy(struOneRes.sztrace_uuid, DymDocument[DYNAMIC_HUMAN_TRACE_UUID].get_utf8().value.to_string().c_str(), sizeof(struOneRes.sztrace_uuid));
				if(DymDocument[DYNAMIC_HUMAN_TRACE_IDX].length())
					struOneRes.trace_idx = DymDocument[DYNAMIC_HUMAN_TRACE_IDX].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_SNAP_TIME].length())
					struOneRes.snap_time = DymDocument[DYNAMIC_HUMAN_SNAP_TIME].get_date().to_int64();
				if(DymDocument[DYNAMIC_HUMAN_DEVICE_ID].length())
					HPR_Strncpy(struOneRes.strudevice_info.szdevice_id, DymDocument[DYNAMIC_HUMAN_DEVICE_ID].get_utf8().value.to_string().c_str(), sizeof(struOneRes.strudevice_info.szdevice_id));
				if(DymDocument[DYNAMIC_HUMAN_DEVICE_TYPE].length())
					struOneRes.strudevice_info.device_type  = DymDocument[DYNAMIC_HUMAN_DEVICE_TYPE].get_int32().value;
				if(DymDocument[DYNAMIC_DEVICE_NAME].length())
					HPR_Strncpy(struOneRes.strudevice_info.szdevice_name, DymDocument[DYNAMIC_DEVICE_NAME].get_utf8().value.to_string().c_str(), sizeof(struOneRes.strudevice_info.szdevice_name));
				if(DymDocument[DYNAMIC_HUMAN_INDEX].length())
		        	struOneRes.index = DymDocument[DYNAMIC_HUMAN_INDEX].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_GLASS].length())
					struOneRes.glass = DymDocument[DYNAMIC_HUMAN_GLASS].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_GENDER].length())
					struOneRes.gender = DymDocument[DYNAMIC_HUMAN_GENDER].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_AGE].length())
					struOneRes.age_range = DymDocument[DYNAMIC_HUMAN_AGE].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_SMILE].length())
					struOneRes.smile = DymDocument[DYNAMIC_HUMAN_SMILE].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_ETHNIC].length())
					struOneRes.ethnic = DymDocument[DYNAMIC_HUMAN_ETHNIC].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_RECT].length())
					HPR_Strncpy(struOneRes.szrect, DymDocument[DYNAMIC_HUMAN_RECT].get_utf8().value.to_string().c_str(), sizeof(struOneRes.szrect));
				if(DymDocument[DYNAMIC_HUMAN_FACE_RECT].length())
					HPR_Strncpy(struOneRes.szface_rect, DymDocument[DYNAMIC_HUMAN_FACE_RECT].get_utf8().value.to_string().c_str(), sizeof(struOneRes.szface_rect));
				if(DymDocument[DYNAMIC_HUMAN_POSE].length())
					HPR_Strncpy(struOneRes.szpose, DymDocument[DYNAMIC_HUMAN_POSE].get_utf8().value.to_string().c_str(), sizeof(struOneRes.szpose));
				if(DymDocument[DYNAMIC_HUMAN_BG_URL].length())
					HPR_Strncpy(struOneRes.szbg_url, DymDocument[DYNAMIC_HUMAN_BG_URL].get_utf8().value.to_string().c_str(), sizeof(struOneRes.szbg_url));
				if(DymDocument[DYNAMIC_HUMAN_FACE_URL].length())
					HPR_Strncpy(struOneRes.szface_url, DymDocument[DYNAMIC_HUMAN_FACE_URL].get_utf8().value.to_string().c_str(), sizeof(struOneRes.szface_url));
				if(DymDocument[DYNAMIC_HUMAN_ERR_CODE].length())
					struOneRes.error_code = DymDocument[DYNAMIC_HUMAN_ERR_CODE].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_VERSION].length())
					struOneRes.version = DymDocument[DYNAMIC_HUMAN_VERSION].get_int64().value;
				if(DymDocument[DYNAMIC_HUMAN_MOD].length())
					struOneRes.mod_id = DymDocument[DYNAMIC_HUMAN_MOD].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_LIB_ID].length())
					HPR_Strncpy(struOneRes.lib_id, DymDocument[DYNAMIC_HUMAN_LIB_ID].get_utf8().value.to_string().c_str(), sizeof(struOneRes.lib_id));
				if(DymDocument[DYNAMIC_HUMAN_HUMAN_ID].length())
					HPR_Strncpy(struOneRes.human_id, DymDocument[DYNAMIC_HUMAN_HUMAN_ID].get_utf8().value.to_string().c_str(), sizeof(struOneRes.human_id));
				if(DymDocument[DYNAMIC_HUMAN_IS_LABELED].length())
					struOneRes.is_labeled = DymDocument[DYNAMIC_HUMAN_IS_LABELED].get_int32().value;

				if(0 == condition.condition.need_model)
				{
					if(DymDocument[DYNAMIC_HUMAN_MODEL_DATA].length())
						memcpy(struOneRes.model, DymDocument[DYNAMIC_HUMAN_MODEL_DATA].get_utf8().value.to_string().c_str(), sizeof(struOneRes.model));
				}
				if(DymDocument[DYNAMIC_HUMAN_DETECT_QUALITY].length())
					struOneRes.detect_quality 		= DymDocument[DYNAMIC_HUMAN_DETECT_QUALITY].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_POINTS_QUALITY].length())
					struOneRes.fPoints_quality 		= (float)DymDocument[DYNAMIC_HUMAN_POINTS_QUALITY].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_EYE_DISTANCE].length())
					struOneRes.fEye_distance 		= (float)DymDocument[DYNAMIC_HUMAN_EYE_DISTANCE].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_COLOR_CONF].length())
					struOneRes.fColor_conf 			= (float)DymDocument[DYNAMIC_HUMAN_COLOR_CONF].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_GRAY_SCALE].length())
					struOneRes.gray_scale 			= DymDocument[DYNAMIC_HUMAN_GRAY_SCALE].get_int32().value;
				if(DymDocument[DYNAMIC_HUMAN_GRAY_MEAN].length())
					struOneRes.fGray_mean 			= (float)DymDocument[DYNAMIC_HUMAN_GRAY_MEAN].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_GRAY_VAR].length())
					struOneRes.fGray_var 			= (float)DymDocument[DYNAMIC_HUMAN_GRAY_VAR].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_CLEARITY].length())
					struOneRes.fClearity 			= (float)DymDocument[DYNAMIC_HUMAN_CLEARITY].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_POSE_PITCH].length())
					struOneRes.fPose_pitch 			= (float)DymDocument[DYNAMIC_HUMAN_POSE_PITCH].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_POSE_YAW].length())
					struOneRes.fPose_yaw 			= (float)DymDocument[DYNAMIC_HUMAN_POSE_YAW].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_POSE_ROLL].length())
					struOneRes.fPose_roll 			= (float)DymDocument[DYNAMIC_HUMAN_POSE_ROLL].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_POSE_CONF].length())
					struOneRes.fPose_conf 			= (float)DymDocument[DYNAMIC_HUMAN_POSE_CONF].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_FRONTAL].length())
					struOneRes.fFrontal 			= (float)DymDocument[DYNAMIC_HUMAN_FRONTAL].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_VISIBLE_QUALITY].length())
					struOneRes.fVisible_quality 	= (float)DymDocument[DYNAMIC_HUMAN_VISIBLE_QUALITY].get_double().value;
				if(DymDocument[DYNAMIC_HUMAN_TOTAL_QUALITY].length())
					struOneRes.fTotal_quality 		= (float)DymDocument[DYNAMIC_HUMAN_TOTAL_QUALITY].get_double().value;
				vecResult.push_back(struOneRes);
			}	
			
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructDynamicHuman search_info failed: %s", xcp.what());
			iRetVal = LS_SERVER_OP_DB_ERR;
			break;
		}
		iRetVal = LS_SERVER_OK;	
	}while (0);	
	
	return iRetVal;
}


HPR_INT32  CStructDynamicHuman::DynamicHumanModelFind(const StruDymFindCondition& condition, vector<StructHumanModelInfo> & vecResult, StruDymSort &struSort)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	std::vector<bsoncxx::document::value> results; 
	do
	{
		try	
		{
			bsoncxx::builder::stream::document filter_builder;
			bsoncxx::builder::stream::document fields;
			
			/*{"_id" : { "$in" : ["xxx","ccc"] } }*/
			if(0 != condition.condition.begin_id.size())
			{
				bsoncxx::stdx::string_view strId = condition.condition.begin_id;
				filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document <<"$gte"<<bsoncxx::types::b_oid{bsoncxx::oid{strId}}<< close_document;
			}
			if(0 != condition.condition.end_id.size())
			{
				bsoncxx::stdx::string_view strId = condition.condition.end_id;
				/*左閉右開*/
				filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document <<"$lt"<<bsoncxx::types::b_oid{bsoncxx::oid{strId}}<< close_document;
			}
			if(0 != condition.condition.human_ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.human_ids) 
				{
					child_builder<<e;
				}
				filter_builder << DYNAMIC_HUMAN_HUMAN_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.struDevice_info.vecDeviceIds.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.struDevice_info.vecDeviceIds) 
				{
					child_builder << e;
				}
				filter_builder << DYNAMIC_HUMAN_DEVICE_ID 	<< open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			
			if(condition.condition.struDevice_info.device_type != -1 )
				filter_builder << DYNAMIC_HUMAN_DEVICE_TYPE    << condition.condition.struDevice_info.device_type;
			if(condition.condition.glass != -1 )
				filter_builder << DYNAMIC_HUMAN_GLASS    	   << condition.condition.glass;
			if(condition.condition.gender != -1 )
				filter_builder << DYNAMIC_HUMAN_GENDER   	   << condition.condition.gender;
			if(condition.condition.age_range != -1)
				filter_builder << DYNAMIC_HUMAN_AGE  	 	   << condition.condition.age_range;
			if(condition.condition.smile != -1)
				filter_builder << DYNAMIC_HUMAN_SMILE          << condition.condition.smile;
			if(condition.condition.ethnic != -1 )
				filter_builder << DYNAMIC_HUMAN_ETHNIC         << condition.condition.ethnic;
			if( condition.condition.result_status != -1 )
				filter_builder << DYNAMIC_HUMAN_ERR_CODE       << condition.condition.result_status;
			if( condition.condition.version != -1 )
				filter_builder << DYNAMIC_HUMAN_VERSION        << condition.condition.version;
			if( condition.condition.mod_id != -1 )
				filter_builder << DYNAMIC_HUMAN_MOD            << condition.condition.mod_id;
			if(condition.condition.end_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$lte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.end_time}}<< close_document;
			if(condition.condition.begin_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$gte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.begin_time}}<< close_document;
			if(condition.skipId.size() != 0 )
			{
				bsoncxx::stdx::string_view strId = condition.skipId;
				if (-1 == struSort.iSortType)
				{
					filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document <<"$lt"<<bsoncxx::types::b_oid{bsoncxx::oid{strId}}<< close_document;
				}
				else if (1 == struSort.iSortType)
				{
					filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document <<"$gt"<<bsoncxx::types::b_oid{bsoncxx::oid{strId}}<< close_document;
				}
			}

			std::string strSort = "";
			if (-1 != struSort.iSortField)
			{
				if (0 == struSort.iSortField)
				{
					strSort = DYNAMIC_HUMAN_TABLE_ID;
				}
				else if (1 == struSort.iSortField)
				{
					strSort = DYNAMIC_HUMAN_SNAP_TIME;
				}
			}
			StruSearchOpt struOpt;
			struOpt.strSort 	= strSort;
			struOpt.iSortType 	= struSort.iSortType;
			struOpt.iLimit 		= condition.limit;
			if(condition.skipId.size() != 0)
			{
				struOpt.iskip = 0;
			}
			else
			{
				struOpt.iskip = condition.offset;
			}
			//STRU_INFO("filter_builder find(%s).sort(%s:%d).limit(%d).offset(%d)", bsoncxx::to_json(filter_builder.view()).c_str(), 
										//struOpt.strSort.c_str(), struOpt.iSortType, struOpt.iLimit, struOpt.iskip);
			fields<< DYNAMIC_HUMAN_TABLE_ID      << 1;
			fields<< DYNAMIC_HUMAN_MODEL_DATA   << 1;
			
			iRetVal = MongoDB::Instance().searchforField(m_dbName, m_collName, filter_builder, results, struOpt, fields);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructStaticHuman::searchforField failed: 0x%x", iRetVal);
				break;
			}
			HPR_UINT32 outlen;

			for (auto  &doc : results)
			{
				auto DymDocument 	= 	doc.view();
				StructHumanModelInfo struOneRes;
			
				if(DymDocument[DYNAMIC_HUMAN_TABLE_ID].length())
					HPR_Strncpy(struOneRes.sz_id, DymDocument[DYNAMIC_HUMAN_TABLE_ID].get_oid().value.to_string().c_str(), sizeof(struOneRes.sz_id));

				if(0 == condition.condition.need_model)
				{
					if(DymDocument[DYNAMIC_HUMAN_MODEL_DATA].length())
						util_tool_base64_decode(DymDocument[DYNAMIC_HUMAN_MODEL_DATA].get_utf8().value.to_string().c_str(), DymDocument[DYNAMIC_HUMAN_MODEL_DATA].get_utf8().value.to_string().size(), (HPR_INT8 *)struOneRes.model, sizeof(struOneRes.model), &outlen);
				}
				vecResult.push_back(struOneRes);
			}
			
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructDynamicHuman DynamicHumanModelFind failed: %s", xcp.what());
			break;
		}
		iRetVal = LS_SERVER_OK;	
	}while (0);	
	return iRetVal;
}

/**@fn      DynamicHumanUpdate
 * @brief    動態庫更新
 * @param   id      		[in]   - 要更新的id
 * @param   struHumanInfo   [in]   - 更新的內容
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32  CStructDynamicHuman::DynamicHumanUpdate(const string& id, StructDynamicInfo& struHumanInfo)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	do
	{
		try	
		{ 
			//auto builder = bsoncxx::builder::stream::document{};
			bsoncxx::builder::stream::document builder;
			builder<< "$set" << open_document;
				if(0 != struHumanInfo.sztrace_uuid[0])
			    	builder<< DYNAMIC_HUMAN_TRACE_UUID 		<< struHumanInfo.sztrace_uuid;
				if(0 != struHumanInfo.trace_idx)
			    	builder<< DYNAMIC_HUMAN_TRACE_IDX 		<< struHumanInfo.trace_idx;
				if(-1 != struHumanInfo.snap_time)
			    	builder<< DYNAMIC_HUMAN_SNAP_TIME 		<< bsoncxx::types::b_date{std::chrono::milliseconds{struHumanInfo.snap_time}};;
				if(0 != struHumanInfo.strudevice_info.szdevice_id[0])
			    	builder<< DYNAMIC_HUMAN_DEVICE_ID 		<< struHumanInfo.strudevice_info.szdevice_id;
				if(0 != struHumanInfo.strudevice_info.device_type)	
			    	builder<< DYNAMIC_HUMAN_DEVICE_TYPE 	<< struHumanInfo.strudevice_info.device_type;
				if(-1 != struHumanInfo.index)	
			    	builder<< DYNAMIC_HUMAN_INDEX 			<< struHumanInfo.index;
				if(-1 != struHumanInfo.glass)
			    	builder<< DYNAMIC_HUMAN_GLASS 			<< struHumanInfo.glass;
				if(-1 != struHumanInfo.gender)
			    	builder<< DYNAMIC_HUMAN_GENDER 			<< struHumanInfo.gender;
				if(-1 != struHumanInfo.age_range)
			    	builder<< DYNAMIC_HUMAN_AGE		 		<< struHumanInfo.age_range;
				if(0 != struHumanInfo.smile)
			   		builder<< DYNAMIC_HUMAN_SMILE 			<< struHumanInfo.smile;
				if(-1 != struHumanInfo.ethnic)
			    	builder<< DYNAMIC_HUMAN_ETHNIC	 		<< struHumanInfo.ethnic;
				if(0 != struHumanInfo.szrect[0])
			    	builder<< DYNAMIC_HUMAN_RECT 			<< struHumanInfo.szrect;
				if(-1 != struHumanInfo.szface_rect[0])
			   	 	builder<< DYNAMIC_HUMAN_FACE_RECT 		<< struHumanInfo.szface_rect;
				if(0 != struHumanInfo.szpose[0])
			    	builder<< DYNAMIC_HUMAN_POSE	 		<< struHumanInfo.szpose;
				if(0 != struHumanInfo.szbg_url[0])
			    	builder<< DYNAMIC_HUMAN_BG_URL 			<< struHumanInfo.szbg_url;
				if(0 != struHumanInfo.szface_url[0])
			    	builder<< DYNAMIC_HUMAN_FACE_URL 		<< struHumanInfo.szface_url;
				if(-1 != struHumanInfo.error_code)
			    	builder<< DYNAMIC_HUMAN_ERR_CODE 		<< struHumanInfo.error_code;
				if(-1 != struHumanInfo.mod_id)
			    	builder<< DYNAMIC_HUMAN_MOD 			<< struHumanInfo.mod_id;
				if(0 != struHumanInfo.lib_id[0])
			    	builder<< DYNAMIC_HUMAN_LIB_ID	 		<< struHumanInfo.lib_id; 
				if(0 != struHumanInfo.human_id[0])
			    	builder<< DYNAMIC_HUMAN_HUMAN_ID 		<< struHumanInfo.human_id; 
				if(0 != struHumanInfo.is_labeled)
			    	builder<< DYNAMIC_HUMAN_IS_LABELED 		<< struHumanInfo.is_labeled; 
				if(0 != struHumanInfo.model[0])
			    	builder<< DYNAMIC_HUMAN_MODEL_DATA 		<< struHumanInfo.model;
				if(-1 != struHumanInfo.detect_quality)
					builder<< DYNAMIC_HUMAN_DETECT_QUALITY	<< struHumanInfo.detect_quality;
				if(-1.0 != struHumanInfo.fPoints_quality)
					builder<< DYNAMIC_HUMAN_POINTS_QUALITY	<< struHumanInfo.fPoints_quality;
				if(-1.0 != struHumanInfo.fEye_distance)
					builder<< DYNAMIC_HUMAN_EYE_DISTANCE  	<< struHumanInfo.fEye_distance;
				if(-1.0 != struHumanInfo.fColor_conf)
					builder<< DYNAMIC_HUMAN_COLOR_CONF    	<< struHumanInfo.fColor_conf;
				if(-1 != struHumanInfo.gray_scale)
					builder<< DYNAMIC_HUMAN_GRAY_SCALE    	<< struHumanInfo.gray_scale;
				if(-1.0 != struHumanInfo.fGray_mean)
					builder<< DYNAMIC_HUMAN_GRAY_MEAN     	<< struHumanInfo.fGray_mean;
				if(-1.0 != struHumanInfo.fGray_var)
					builder<< DYNAMIC_HUMAN_GRAY_VAR      	<< struHumanInfo.fGray_var;
				if(-1.0 != struHumanInfo.fClearity)
					builder<< DYNAMIC_HUMAN_CLEARITY      	<< struHumanInfo.fClearity;
				if(-1.0 != struHumanInfo.fPose_pitch)
					builder<< DYNAMIC_HUMAN_POSE_PITCH    	<< struHumanInfo.fPose_pitch;
				if(-1.0 != struHumanInfo.fPose_yaw)
					builder<< DYNAMIC_HUMAN_POSE_YAW	    << struHumanInfo.fPose_yaw;
				if(-1.0 != struHumanInfo.fPose_roll)
					builder<< DYNAMIC_HUMAN_POSE_ROLL     	<< struHumanInfo.fPose_roll;
				if(-1.0 != struHumanInfo.fPose_conf)
					builder<< DYNAMIC_HUMAN_POSE_CONF     	<< struHumanInfo.fPose_conf;
				if(-1.0 != struHumanInfo.fFrontal)
					builder<< DYNAMIC_HUMAN_FRONTAL	     	<< struHumanInfo.fFrontal;
				if(-1.0 != struHumanInfo.fVisible_quality)
					builder<< DYNAMIC_HUMAN_VISIBLE_QUALITY	<< struHumanInfo.fVisible_quality;
				if(-1.0 != struHumanInfo.fTotal_quality)
					builder<< DYNAMIC_HUMAN_TOTAL_QUALITY 	<< struHumanInfo.fTotal_quality;
			builder<< close_document;

			STRU_DEBUG("doc_value  %s  ", bsoncxx::to_json(builder.view()).c_str());

			bsoncxx::builder::stream::document filter_builder;
			bsoncxx::stdx::string_view strId = id;
			filter_builder << DYNAMIC_HUMAN_TABLE_ID  << bsoncxx::types::b_oid{bsoncxx::oid{strId}};
			
			iRetVal = MongoDB::Instance().find_and_update(m_dbName, m_collName, filter_builder, builder);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructStaticHuman::update_many failed: 0x%x", iRetVal);
				break;
			}
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructStaticHuman::insert_one failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}

/**@fn      DynamicHumanDelete
 * @brief    動態庫刪除
 * @param   lDate      		[in]   - 待刪除的日期
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32  CStructDynamicHuman::DynamicHumanDelete(const HPR_INT64& lDate)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	do
	{
		try	
		{ 
			UTIL_IVMS_TIME_T struTime;
			HPR_INT64 timeStamp = 0;
			
			util_tool_convert_utc_to_ivms(lDate, &struTime);
			struTime.iHour 		= 0;
			struTime.iMin 		= 0;
			struTime.iSecond 	= 0;
			struTime.iMsecond 	= 0;
			util_tool_convert_ivms_to_utc(&timeStamp, &struTime);
			timeStamp += 86400000; //加1天
			bsoncxx::builder::stream::document filter_builder;
			
			filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$lte"<<bsoncxx::types::b_date{std::chrono::milliseconds{timeStamp}}<< close_document;
			
			iRetVal = MongoDB::Instance().delete_many(m_dbName, m_collName, filter_builder);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructDynamicHuman::delete_many failed: 0x%x", iRetVal);
				break;
			}
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructDynamicHuman::DynamicHumanDelete failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}

/**@fn      DynamicHumanTotalCount
 * @brief    動態庫統計
 * @param   condition      	[in]    - 過濾條件
 * @param   total      		[out]   - 統計結果
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32 CStructDynamicHuman:: DynamicHumanTotalCount(const StruDymFindCondition& condition, HPR_INT32&  total)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	do
	{
		try	
		{ 
			bsoncxx::builder::stream::document filter_builder;
			
			/*{"_id" : { "$in" : ["xxx","ccc"] } }*/
			if(0 != condition.condition.ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.ids) 
				{
					bsoncxx::stdx::string_view strId = e;   //轉換成bsoncxx::stdx::string_view 是因爲mongo-cxx-driver源碼裏對b_oid類型的初始化有BUG,char*類型初始化不會成功
					child_builder<< bsoncxx::types::b_oid{bsoncxx::oid{strId}};
				}
				filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.human_ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.human_ids) 
				{
					child_builder<<e;
				}
				filter_builder << DYNAMIC_HUMAN_HUMAN_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.struDevice_info.vecDeviceIds.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.struDevice_info.vecDeviceIds) 
				{
					child_builder << e;
				}
				filter_builder << DYNAMIC_HUMAN_DEVICE_ID 	<< open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			
			if(condition.condition.struDevice_info.device_type != -1 )
				filter_builder << DYNAMIC_HUMAN_DEVICE_TYPE    << condition.condition.struDevice_info.device_type;
			if(condition.condition.glass != -1 )
				filter_builder << DYNAMIC_HUMAN_GLASS    	   << condition.condition.glass;
			if(condition.condition.gender != -1 )
				filter_builder << DYNAMIC_HUMAN_GENDER   	   << condition.condition.gender;
			if(condition.condition.age_range != -1)
				filter_builder << DYNAMIC_HUMAN_AGE  	 	   << condition.condition.age_range;
			if(condition.condition.smile != -1)
				filter_builder << DYNAMIC_HUMAN_SMILE          << condition.condition.smile;
			if(condition.condition.ethnic != -1 )
				filter_builder << DYNAMIC_HUMAN_ETHNIC         << condition.condition.ethnic;
			if( condition.condition.result_status != -1 )
				filter_builder << DYNAMIC_HUMAN_ERR_CODE       << condition.condition.result_status;
			if( condition.condition.version != -1 )
				filter_builder << DYNAMIC_HUMAN_VERSION        << condition.condition.version;
			if( condition.condition.mod_id != -1 )
				filter_builder << DYNAMIC_HUMAN_MOD            << condition.condition.mod_id;
			if(condition.condition.end_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$lte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.end_time}}<< close_document;
			if(condition.condition.begin_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$gte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.begin_time}}<< close_document;

			STRU_DEBUG("filter_builder count(%s)", bsoncxx::to_json(filter_builder.view()).c_str());

			iRetVal = MongoDB::Instance().coll_count(m_dbName, m_collName, filter_builder, total);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructDynamicHuman::insert_one failed: 0x%x", iRetVal);
				break;
			}
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructDynamicHuman::insert_one failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}

/**@fn      DynamicHumanDateCount
 * @brief    動態庫按日期統計
 * @param   condition      	[in]    - 過濾條件
 * @param   total      		[out]   - 統計結果
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32 CStructDynamicHuman:: DynamicHumanDateCount(const StruDymFindCondition& condition, StruDymGroup struGroupType, vector<StruDateCountResult>& vecCountResult)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	do
	{
		try	
		{ 
			bsoncxx::builder::stream::document filter_builder;
			bsoncxx::builder::stream::document group_builder;
			/*{"_id" : { "$in" : ["xxx","ccc"] } }*/
			if(0 != condition.condition.ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.ids) 
				{
					bsoncxx::stdx::string_view strId = e;   //轉換成bsoncxx::stdx::string_view 是因爲mongo-cxx-driver源碼裏對b_oid類型的初始化有BUG,char*類型初始化不會成功
					child_builder<< bsoncxx::types::b_oid{bsoncxx::oid{strId}};
				}
				filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.human_ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.human_ids) 
				{
					child_builder<<e;
				}
				filter_builder << DYNAMIC_HUMAN_HUMAN_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.struDevice_info.vecDeviceIds.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.struDevice_info.vecDeviceIds) 
				{
					child_builder << e;
				}
				filter_builder << DYNAMIC_HUMAN_DEVICE_ID 	<< open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			
			if(condition.condition.struDevice_info.device_type != -1 )
				filter_builder << DYNAMIC_HUMAN_DEVICE_TYPE    << condition.condition.struDevice_info.device_type;
			if(condition.condition.glass != -1 )
				filter_builder << DYNAMIC_HUMAN_GLASS    	   << condition.condition.glass;
			if(condition.condition.gender != -1 )
				filter_builder << DYNAMIC_HUMAN_GENDER   	   << condition.condition.gender;
			if(condition.condition.age_range != -1)
				filter_builder << DYNAMIC_HUMAN_AGE  	 	   << condition.condition.age_range;
			if(condition.condition.smile != -1)
				filter_builder << DYNAMIC_HUMAN_SMILE          << condition.condition.smile;
			if(condition.condition.ethnic != -1 )
				filter_builder << DYNAMIC_HUMAN_ETHNIC         << condition.condition.ethnic;
			if( condition.condition.result_status != -1 )
				filter_builder << DYNAMIC_HUMAN_ERR_CODE       << condition.condition.result_status;
			if( condition.condition.version != -1 )
				filter_builder << DYNAMIC_HUMAN_VERSION        << condition.condition.version;
			if( condition.condition.mod_id != -1 )
				filter_builder << DYNAMIC_HUMAN_MOD            << condition.condition.mod_id;
			if(condition.condition.end_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$lte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.end_time}}<< close_document;
			if(condition.condition.begin_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$gte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.begin_time}}<< close_document;

			STRU_DEBUG("filter_builder count(%s)", bsoncxx::to_json(filter_builder.view()).c_str());
			mongocxx::pipeline pipeline;
			std::vector<bsoncxx::document::value> results;
			if(0 == struGroupType.iGroupType)
			{
				/*按年月日小時統計*/
				group_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<< "year"<<open_document<<"$year"<<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document;
				group_builder << "month" << open_document <<"$month"      <<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document;
				group_builder << "day"   << open_document <<"$dayOfMonth" <<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document;
				group_builder << "hour"  << open_document <<"$hour"       <<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document<< close_document;
				group_builder << "count" << open_document << "$sum" << 1  <<close_document;
			}
			else if(1 == struGroupType.iGroupType)
			{
				/*按年月日統計*/
				group_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<< "year"<<open_document<<"$year"<<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document;
				group_builder << "month" << open_document <<"$month"      <<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document;
				group_builder << "day"   << open_document <<"$dayOfMonth" <<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document<< close_document;
				group_builder << "count" << open_document << "$sum" << 1  <<close_document;
			}
			else if(2 == struGroupType.iGroupType)
			{
				/*按年月統計*/
				group_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<< "year"<<open_document<<"$year"<<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document;
				group_builder << "month" << open_document <<"$month"     <<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document<< close_document;
				group_builder << "count" << open_document << "$sum" << 1 <<close_document;
			}
			else if(3 == struGroupType.iGroupType)
			{
				/*按年統計*/
				group_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<< "year"<<open_document<<"$year"<<"$"DYNAMIC_HUMAN_SNAP_TIME<<close_document<< close_document;
				group_builder << "count" << open_document << "$sum" << 1 <<close_document;
			}
			
			STRU_DEBUG("group (%s)", bsoncxx::to_json(group_builder.view()).c_str());
			pipeline.match(filter_builder.view());
			pipeline.group(group_builder.view());
			iRetVal = MongoDB::Instance().aggregate(m_dbName, m_collName, pipeline, results);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructAlarmHuman::AlarmHumanFind failed: 0x%x", iRetVal);
				break;
			}
			for (auto  &doc : results)
			{
				auto DateCountDocument 	= 	doc.view();
				StruDateCountResult struOneRes;
				stringstream streamKey;
				
				auto op_view = DateCountDocument[DYNAMIC_HUMAN_TABLE_ID].get_document().view();
				bsoncxx::document::view::const_iterator iter = 	op_view.begin();
				for(;iter != op_view.end(); iter++)
				{
					streamKey.fill('0');
					streamKey.width(2); 
					bsoncxx::document::view::const_iterator tempiter = iter;
					bsoncxx::document::element elem;
					elem = *iter;
					streamKey<<elem.get_int32().value;
					if(++tempiter == op_view.end())
					{
						//最後一個"-"不添加
						break;
					}
					streamKey<<"-";
				}
				struOneRes.strGroupKey = streamKey.str();
				struOneRes.iCount 	   = DateCountDocument["count"].get_int32().value;
				vecCountResult.push_back(struOneRes);
				STRU_DEBUG("DateCountDocument=%s ", bsoncxx::to_json(DateCountDocument).c_str());
			}
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructDynamicHuman::DynamicHumanDateCount failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}


/**@fn      DynamicHumanDistinct
 * @brief    動態庫統計
 * @param   condition      	[in]    - 過濾條件
 * @param   total      		[out]   - 統計結果
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32 CStructDynamicHuman:: DynamicHumanDistinct(string distinctName, const StruDymFindCondition& condition, vector<string> &vecResaults)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	std::vector<bsoncxx::document::value> results; 
	string outString;
	do
	{
		try	
		{ 
			bsoncxx::builder::stream::document filter_builder;
			
			/*{"_id" : { "$in" : ["xxx","ccc"] } }*/
			if(0 != condition.condition.ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.ids) 
				{
					bsoncxx::stdx::string_view strId = e;   //轉換成bsoncxx::stdx::string_view 是因爲mongo-cxx-driver源碼裏對b_oid類型的初始化有BUG,char*類型初始化不會成功
					child_builder<< bsoncxx::types::b_oid{bsoncxx::oid{strId}};
				}
				filter_builder << DYNAMIC_HUMAN_TABLE_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.human_ids.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.human_ids) 
				{
					child_builder<<e;
				}
				filter_builder << DYNAMIC_HUMAN_HUMAN_ID << open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(0 != condition.condition.struDevice_info.vecDeviceIds.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.struDevice_info.vecDeviceIds) 
				{
					child_builder << e;
				}
				filter_builder << DYNAMIC_HUMAN_DEVICE_ID 	<< open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if (0 != condition.condition.lib_id.size())
			{
				bsoncxx::builder::stream::array child_builder;
				for (auto &e : condition.condition.lib_id) 
				{
					child_builder << e;
				}
				filter_builder << DYNAMIC_HUMAN_LIB_ID 	<< open_document<<"$in"<<open_array<< bsoncxx::builder::concatenate(child_builder.view())<<close_array<<close_document;
			}
			if(condition.condition.struDevice_info.device_type != -1 )
				filter_builder << DYNAMIC_HUMAN_DEVICE_TYPE    << condition.condition.struDevice_info.device_type;
			if(condition.condition.glass != -1 )
				filter_builder << DYNAMIC_HUMAN_GLASS    	   << condition.condition.glass;
			if(condition.condition.gender != -1 )
				filter_builder << DYNAMIC_HUMAN_GENDER   	   << condition.condition.gender;
			if(condition.condition.age_range != -1)
				filter_builder << DYNAMIC_HUMAN_AGE  	 	   << condition.condition.age_range;
			if(condition.condition.smile != -1)
				filter_builder << DYNAMIC_HUMAN_SMILE          << condition.condition.smile;
			if(condition.condition.ethnic != -1 )
				filter_builder << DYNAMIC_HUMAN_ETHNIC         << condition.condition.ethnic;
			if( condition.condition.result_status != -1 )
				filter_builder << DYNAMIC_HUMAN_ERR_CODE       << condition.condition.result_status;
			if( condition.condition.version != -1 )
				filter_builder << DYNAMIC_HUMAN_VERSION        << condition.condition.version;
			if( condition.condition.mod_id != -1 )
				filter_builder << DYNAMIC_HUMAN_MOD            << condition.condition.mod_id;
			if( condition.condition.is_labeled != -1 )
				filter_builder << DYNAMIC_HUMAN_IS_LABELED     << condition.condition.is_labeled;
			if(condition.condition.end_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$lte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.end_time}}<< close_document;
			if(condition.condition.begin_time != -1 )
				filter_builder << DYNAMIC_HUMAN_SNAP_TIME << open_document <<"$gte"<<bsoncxx::types::b_date{std::chrono::milliseconds{condition.condition.begin_time}}<< close_document;

			STRU_DEBUG("distinctName %s,filter_builder distinct(%s)", distinctName.c_str(), bsoncxx::to_json(filter_builder.view()).c_str());

			iRetVal = MongoDB::Instance().distinct(m_dbName, m_collName, distinctName, filter_builder, results);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructDynamicHuman::distinct failed: 0x%x", iRetVal);
				break;
			}
			for (auto  &doc : results)
			{
				auto DymDocument 	= 	doc.view();
				bsoncxx::document::element values = DymDocument["values"];
				auto arrValues = 	values.get_array().value;
				for (auto&& elem : arrValues) 
				{
					outString.clear();
					if(bsoncxx::type::k_int32 == elem.type())
					{
						my_to_string(outString, elem.get_int32().value);
					}
					else if(bsoncxx::type::k_utf8 == elem.type())
					{
						my_to_string(outString, elem.get_utf8().value.to_string());
					}
					else if(bsoncxx::type::k_double == elem.type())
					{
						my_to_string(outString, elem.get_double().value);
					}
					else if(bsoncxx::type::k_date == elem.type())
					{
						my_to_string(outString, elem.get_date().to_int64());
					}
					else if(bsoncxx::type::k_int64 == elem.type())
					{
						my_to_string(outString, elem.get_int64().value);
					}
					vecResaults.push_back(outString);
				}
				
			}	
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructDynamicHuman::distinct failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}


HPR_INT32 CStructDynamicHuman::DynamicHumanSplitData()
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	do
	{
		try	
		{ 
			bsoncxx::builder::stream::document command;
			bsoncxx::document::view result;
			std::vector<bsoncxx::document::value> results;
			HPR_UINT64 maxChunkSize  	= 0;
			HPR_INT32 iTotalCount    	= 0;
			HPR_INT32 iAvageSize   		= 0;
			StruDymFindCondition condition;

			StruDymSort struSort;
			struSort.iSortField = 0;
			struSort.iSortType  = -1;		
			StruDymFindCondition struCondition;
			struCondition.limit = 1;
			struCondition.skipId.clear();
			vector<StructHumanModelInfo> vecResult;		
			/* 查詢最後一條數據,如果數據沒有增加,則不切分數據 */
			iRetVal = DynamicHumanModelFind(struCondition, vecResult, struSort);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("DynamicHumanModelFind  failed ");
				break;
			}
			if(0 == vecResult.size())
			{
				return LS_SERVER_OK;
			}
			if(0 == m_strLastData.compare(vecResult[0].sz_id))
			{
				STRU_DEBUG("don't need to split data");
				return LS_SERVER_OK;
			}
			m_strLastData.assign(vecResult[0].sz_id);
			/* 統計總數 */
			iRetVal = CStructDynamicHuman::Instance().DynamicHumanTotalCount(condition, iTotalCount);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("StaticHumanTotalCount  failed ");
				break;
			}
			/* 統計每條數據平均大小 */
			iRetVal = CStructDynamicHuman::Instance().DynamicHumanAvageSize(iAvageSize);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("DynamicHumanAvageSize  failed ");
				break;
			}
			
			/*切分數據,每段數據大小計算公式*/
			maxChunkSize  = ((iTotalCount/(DY_PARTION_COUNT-1)-1)*2*iAvageSize)/(1024*1024);
			maxChunkSize  = (maxChunkSize > 0) ? maxChunkSize: 1;
			command<< "splitVector" 	<< DYNAMIC_HUMAN_DB_NAME "." DYNAMIC_HUMAN_COLL_NAME;
			command<< "keyPattern"  	<< open_document << DYNAMIC_HUMAN_SNAP_TIME << 1 << close_document;
			command<< "maxChunkSize"  	<< (HPR_INT64)maxChunkSize;
			command<< "maxChunkObjects" << iTotalCount;
			command<< "maxSplitPoints"  << DY_PARTION_COUNT;
			STRU_DEBUG("doc_value  %s  ,avgObjSize %ld", bsoncxx::to_json(command.view()).c_str(), iAvageSize);
			iRetVal = MongoDB::Instance().run_command(m_dbName, command, results);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructStaticHuman::run_command failed: 0x%x", iRetVal);
				break;
			}
			auto current_op = results[0].view(); 
			
			HPR_Guard stGuard0(&m_timeLock);
			m_vecSplitId.clear();
			auto ids = current_op["splitKeys"].get_array().value;
			for (auto&& it : ids) 
			{
				auto id_view = it.get_document().view();
				m_vecSplitId.push_back(id_view[DYNAMIC_HUMAN_SNAP_TIME].get_date().to_int64());
				
			}
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructStaticHuman::StaticHumanSplitData failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}


HPR_VOID CStructDynamicHuman::DynamicHumanGetSplitData(vector<HPR_INT64>&             vecSplitId)
{
	HPR_Guard stGuard0(&m_timeLock);
	vecSplitId = m_vecSplitId;
	return;
}

HPR_INT32 CStructDynamicHuman::DynamicHumanAvageSize(HPR_INT32 &iAvageSize)
{
	HPR_INT32 iRetVal = LS_SERVER_ERR;
	do
	{
		try	
		{ 
			bsoncxx::builder::stream::document command;
			bsoncxx::document::view result;
			std::vector<bsoncxx::document::value> results;

			command << "collStats" << DYNAMIC_HUMAN_COLL_NAME;
		
			
			STRU_DEBUG("doc_value  %s  ", bsoncxx::to_json(command.view()).c_str());
			iRetVal = MongoDB::Instance().run_command(m_dbName, command, results);
			if(LS_SERVER_OK != iRetVal)
			{
				STRU_ERROR("CStructStaticHuman::run_command failed: 0x%x", iRetVal);
				break;
			}
			auto current_op = results[0].view(); 
			iAvageSize = current_op["avgObjSize"].get_int32().value;
		}
		catch (const std::exception& xcp) 
		{
		 	STRU_ERROR("CStructStaticHuman::DynamicHumanAvageSize failed: %s", xcp.what());
			return iRetVal;
		}
		
		iRetVal = LS_SERVER_OK;	
	}while(0);
	return iRetVal;
}

						
/**@fn      SetDyHumanInfoHook
 * @brief    設置動態庫信息回調函數
 * @param   func      		[in]   - 回調函數
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32 CStructDynamicHuman::SetDyHumanInfoHook(DyHumanInfoHook func)
{
	if(func != NULL)
	{
		m_DyHumanInfofunc = func;
	}
	else
	{	
		return LS_SERVER_ERR;
	}

	return LS_SERVER_OK;

}

/**@fn      cache_bath_insert_task
 * @brief    批量插入檢測線程
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_INT32 CStructDynamicHuman::cache_bath_insert_task()
{	
	HPR_INT32 iRetVal = LS_SERVER_OP_DB_ERR;
	do
	{
		try 
		{
			for(HPR_UINT32 iTaskIndex = 0; iTaskIndex < m_vecBatchInsertOp.size(); iTaskIndex++)
			{
				if ((m_vecBatchInsertOp[iTaskIndex].bathInsertDocuments.size() != 0))
				{
					HPR_INT32		   bThread		 = HPR_ERROR;
					m_vecBatchInsertOp[iTaskIndex].vecTaskCopy.nIndex = CGlobalRes::Instance().GetThreadID();
					//STRU_INFO("get id %d task[%d],need insert[%ld]!!!",	m_vecTaskCopy[iTaskIndex].nIndex, iTaskIndex, m_bathInsertDocuments[iTaskIndex].size());
					m_vecBatchInsertOp[iTaskIndex].vecTaskCopy.nTaskId = iTaskIndex;
					bThread = HPR_ThreadPool_WorkEx(CGlobalRes::Instance().GetThreadPoolHand(),Dynamic_human_sub_insert_thread,(HPR_VOIDPTR)&m_vecBatchInsertOp[iTaskIndex].vecTaskCopy,HPR_FALSE);
					if (HPR_OK != bThread)
					{
						CGlobalRes::Instance().PushThreadID(m_vecBatchInsertOp[iTaskIndex].vecTaskCopy.nIndex);
						STRU_ERROR("thread %d creat error [%d]", m_vecBatchInsertOp[iTaskIndex].vecTaskCopy.nIndex, bThread);
						continue;
					}
					HPR_SemWait(&(m_vecBatchInsertOp[iTaskIndex].vecTaskCopy.semSync));
				}
			}
		}
		catch (const std::exception& xcp) 
		{
			STRU_ERROR("CStructDynamicHuman::cache_bath_insert_task failed: %s", xcp.what());
			break;
		}
		iRetVal = LS_SERVER_OK;	
	}while (0);	
	
	return iRetVal;
}

/**@fn      cache_bath_sub_insert_task
 * @brief    插入線程
 * @param   iTaskIndex     		[in]   - 數據隊列編號
 * @return  錯誤碼: 成功 DB_SUCCESS
 * @note   
 */
HPR_VOID CStructDynamicHuman::cache_bath_sub_insert_task(HPR_INT32 &iTaskIndex, HPR_SEM_T &semSync)
{
	HPR_INT32 iTimes = 0;
	HPR_INT64 lversion = 0;
	VEC_DOCUMENTS DyHumanDocument;
	{
		HPR_Guard stGuard0(&(m_vecBatchInsertOp[iTaskIndex].xLock));
		DyHumanDocument.swap(m_vecBatchInsertOp[iTaskIndex].bathInsertDocuments);
		lversion	=m_vecBatchInsertOp[iTaskIndex].version;
		m_vecBatchInsertOp[iTaskIndex].version 		   = get_time();
		HPR_SemPost(&semSync);
	}
	if(DyHumanDocument.size() != 0)
	{
		do
		{
			if(LS_SERVER_OK != MongoDB::Instance().bulk_write(m_dbName, m_collName, DyHumanDocument, HPR_TRUE))
			{
				STRU_ERROR("CStructStaticHuman::insert_many failed cache[%ld]", DyHumanDocument.size());
				iTimes++;
				if(iTimes > 3)
				{
					DyHumanDocument.clear();
					iTimes = 0;
				}
			}
			else
			{
				STRU_INFO("thread %d insert_many [%ld]", iTaskIndex, DyHumanDocument.size());
				DyHumanDocument.clear();
				//插入成功後通知上層
				if(NULL != m_DyHumanInfofunc)
				{	
					StruDymFindCondition condition;
					vector<StructDynamicInfo> vecResult;
					StruDymSort struSort;
					condition.condition.version = lversion;
					if(LS_SERVER_OK == DynamicHumanFind(condition, vecResult, struSort))
					{
						(*m_DyHumanInfofunc)(vecResult);
					}
				}
			}
		}while (iTimes > 0);
		
	}
	return NULL;
}

HPR_TIME_T CStructDynamicHuman::get_time()
{
	HPR_Guard stGuard0(&m_timeLock);
	HPR_TIME_T ltime = HPR_TimeNow();
	return ltime;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章