package com.commons.core.storage.mongoDb;
import com.commons.core.CommonErrorCode;
import com.commons.core.storage.mongoDb.config.MongoDbConfig;
import com.commons.core.storage.mongoDb.config.MongoDbStorageConfig;
import com.happyelements.rdcenter.commons.throwable.HeException;
import com.mongodb.*;
import java.util.*;
/**fls
*
*/
public class MongoDbManager {
private static MongoDbManager instance;
private Map<String, MongoClient> mongoDbMap = new HashMap<String, MongoClient>();
public static MongoDbManager getInstance() {
if (instance == null) {
synchronized (MongoDbManager.class) {
if (instance == null) {
instance = new MongoDbManager();
}
}
}
return instance;
}
private MongoDbManager() {
try {
initMongoDbMap();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
private void initMongoDbMap() throws Exception {
MongoDbConfig config = MongoDbConfig.getInstance();
if (config == null) {
throw new IllegalStateException(
"db config null, failed to read config file mongo_db.xml from remote");
}
for (MongoDbConfig.DbServerDesc item : config.getDbItemConfigList()) {
mongoDbMap.put(item.getName(), new MongoClient(new ServerAddress(item.getHost(), item.getPort()),
MongoClientOptions.builder().maxConnectionLifeTime(item.getMaxConnectionLifeTime())
.connectionsPerHost(item.getConnectionsPerHost())
.minConnectionsPerHost(item.getMinConnectionsPerHost())
.connectTimeout(item.getConnectTimeout())
.build()));
}
}
private MongoClient getMongoDbInstance(String dbName) {
return this.mongoDbMap.get(dbName);
}
private MongoClient getMongoDb(String dbName) {
return getMongoDbInstance(dbName);
}
private DB getGeoDB(String dbName) {
MongoDbConfig.DbServerDesc dbItemConfig = MongoDbConfig.getInstance().getDbItemConfig(dbName);
if (dbItemConfig == null) {
throw new HeException(CommonErrorCode.PARAMETER_ERROR);
}
DB db = getMongoDb(dbName).getDB(dbItemConfig.getDatabase());
return db;
}
private DBCollection getGeoCollection(String dbName, String collectionName) {
MongoDbConfig.DbServerDesc dbItemConfig = MongoDbConfig.getInstance().getDbItemConfig(dbName);
if (dbItemConfig == null) {
throw new HeException(CommonErrorCode.PARAMETER_ERROR);
}
DB db = getMongoDb(dbName).getDB(dbItemConfig.getDatabase());
DBCollection collection = db.getCollection(collectionName);
BasicDBObject ensureObject = new BasicDBObject("loc", "2dsphere");
collection.createIndex(ensureObject);
return collection;
}
/**
* 存入地理点信息
* @param uid
* @param longitude
* @param latitude
* @param addParam
* @param storageConfig
*/
public void saveGeoPointData(long uid, double longitude, double latitude, Map addParam, MongoDbStorageConfig storageConfig) {
BasicDBList coordinates = new BasicDBList();
coordinates.put(0, longitude);
coordinates.put(1, latitude);
BasicDBObject insertObj = new BasicDBObject("_id", uid)
.append("loc", new BasicDBObject("type", "Point").append("coordinates", coordinates));
if (!addParam.isEmpty()) {
for (Iterator iter = addParam.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
insertObj.append(String.valueOf(entry.getKey()), entry.getValue());
}
}
DBCollection collection = getGeoCollection(storageConfig.getDbName(), storageConfig.getCollectionName());
collection.save(insertObj);
}
/**
* 查找地理位置附近的信息
* @param longitude
* @param latitude
* @param limitNum
* @param storageConfig
* @param excludeList
* @return
*/
public List<Map> findNearData(double longitude, double latitude, int limitNum, MongoDbStorageConfig storageConfig, List<Long> excludeList) {
BasicDBList myLocation = new BasicDBList();
myLocation.put(0, longitude);
myLocation.put(1, latitude);
DBCollection collection = getGeoCollection(storageConfig.getDbName(), storageConfig.getCollectionName());
DBCursor cursor = collection.find(
new BasicDBObject("loc",
new BasicDBObject("$near",
new BasicDBObject("$geometry",
new BasicDBObject("type", "Point")
.append("coordinates", myLocation))
)
).append("_id", new BasicDBObject("$nin", excludeList))
).limit(limitNum);
List<Map> objectList = new ArrayList<Map>();
try {
while (cursor.hasNext()) {
objectList.add(cursor.next().toMap());
}
} finally {
cursor.close();
}
return objectList;
}
/**
* 查找地理位置附近的信息(用于分布式查找)
* @param longitude
* @param latitude
* @param limitNum
* @param storageConfig
* @param excludeList
* @return
*/
public List<Map> findGeoNearData(double longitude, double latitude, int limitNum, MongoDbStorageConfig storageConfig, List<Long> excludeList) {
BasicDBList myLocation = new BasicDBList();
myLocation.put(0, longitude);
myLocation.put(1, latitude);
DB db = getGeoDB(storageConfig.getDbName());
CommandResult result = db.command(
new BasicDBObject("geoNear", storageConfig.getCollectionName())
.append("near", new BasicDBObject("type", "Point")
.append("coordinates", myLocation))
.append("spherical", true)
.append("limit", limitNum)
.append("query", new BasicDBObject("_id", new BasicDBObject("$nin", excludeList)))
);
List<Map> objectList = new ArrayList<Map>();
BasicDBList retList = (BasicDBList)result.get("results");
try {
for (int i = 0; i < retList.size(); i++) {
BasicDBObject tempList = (BasicDBObject)retList.get(i);
DBObject bo = (DBObject)tempList.get("obj");
objectList.add(bo.toMap());
}
} finally {
result.clear();
}
return objectList;
}
/**
* 查找一个用户数据
* @param uid
* @param storageConfig
* @return
*/
public Map findOneGeoUser(long uid, MongoDbStorageConfig storageConfig) {
DBCollection collection = getGeoCollection(storageConfig.getDbName(), storageConfig.getCollectionName());
DBObject dbObject = collection.findOne(
new BasicDBObject("_id", uid)
);
if (dbObject == null) {
return null;
}
return dbObject.toMap();
}
/**
* 称除用户
* @param uid
* @param storageConfig
* @return
*/
public boolean removeOneGeoUser(long uid, MongoDbStorageConfig storageConfig) {
DBCollection collection = getGeoCollection(storageConfig.getDbName(), storageConfig.getCollectionName());
collection.remove(
new BasicDBObject("_id", uid)
);
return true;
}
/**
* 清空整个数据库
* @param storageConfig
* @return
*/
public boolean clearGeoData(MongoDbStorageConfig storageConfig) {
DBCollection collection = getGeoCollection(storageConfig.getDbName(), storageConfig.getCollectionName());
collection.drop();
return true;
}
}