MongoDBPro.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. package com.yihu.hos.common.mongo;
  2. import com.fasterxml.jackson.databind.JsonNode;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import com.mongodb.MongoNamespace;
  5. import com.mongodb.client.*;
  6. import com.mongodb.client.model.*;
  7. import com.mongodb.client.result.DeleteResult;
  8. import com.mongodb.client.result.UpdateResult;
  9. import org.apache.commons.lang3.StringUtils;
  10. import org.bson.Document;
  11. import java.io.IOException;
  12. import java.util.ArrayList;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * MongoDBPro. Professional database CURD and Manager tool.
  18. *
  19. * @created Airhead 2016/2/17.
  20. */
  21. public class MongoDBPro implements IMongoDBRunner, IMongoDBAdminer {
  22. private static final Map<String, MongoDBPro> map = new HashMap<String, MongoDBPro>();
  23. private final MongoDBConfig config;
  24. public MongoDBPro() {
  25. if (MongoDBKit.config == null) {
  26. throw new RuntimeException("The main config is null, initialize MonogDBKit first");
  27. }
  28. this.config = MongoDBKit.config;
  29. }
  30. public MongoDBPro(String configName) {
  31. this.config = MongoDBKit.getConfig(configName);
  32. if (this.config == null) {
  33. throw new IllegalArgumentException("Config not found by configName: " + configName);
  34. }
  35. }
  36. public static MongoDBPro use() {
  37. return use(MongoDBKit.config.name);
  38. }
  39. public static MongoDBPro use(String configName) {
  40. MongoDBPro result = map.get(configName);
  41. if (result == null) {
  42. result = new MongoDBPro(configName);
  43. map.put(configName, result);
  44. }
  45. return result;
  46. }
  47. public MongoDBPro db(String databaseName) {
  48. config.getDatabase(databaseName);
  49. return this;
  50. }
  51. @Override
  52. public long count(String collectionName) {
  53. return count(collectionName, null);
  54. }
  55. @Override
  56. public long count(String collectionName, String filter) {
  57. return count(collectionName, filter, null);
  58. }
  59. /**
  60. * @param collectionName
  61. * @param filter the query filter
  62. * @param options the options describing the count
  63. * <p>
  64. * {
  65. * limit: <integer>,
  66. * skip: <integer>,
  67. * hint: <hint>
  68. * }
  69. * @return
  70. */
  71. @Override
  72. public long count(String collectionName, String filter, String options) {
  73. MongoCollection<Document> collection = getCollection(collectionName);
  74. Document filterDocument = new Document();
  75. if (filter != null) {
  76. filterDocument = Document.parse(filter);
  77. }
  78. CountOptions countOptions = new CountOptions();
  79. if (options != null) {
  80. ObjectMapper mapper = new ObjectMapper();
  81. try {
  82. JsonNode rootNode = mapper.readValue(options, JsonNode.class);
  83. String hintString = rootNode.path("hint").toString();
  84. if (!StringUtils.isEmpty(hintString)) {
  85. Document hint = Document.parse(hintString);
  86. countOptions.hint(hint);
  87. } else {
  88. countOptions.hint(new Document());
  89. }
  90. countOptions.limit(rootNode.path("limit").asInt());
  91. countOptions.skip(rootNode.path("skip").asInt());
  92. } catch (IOException e) {
  93. e.printStackTrace();
  94. }
  95. }
  96. return collection.count(filterDocument, countOptions);
  97. }
  98. @Override
  99. public List<String> find(String collectionName) {
  100. return find(collectionName, null);
  101. }
  102. @Override
  103. public List<String> find(String collectionName, String filter) {
  104. return find(collectionName, filter, null);
  105. }
  106. @Override
  107. public List<String> find(String collectionName, String filter, String projection) {
  108. return find(collectionName, filter, projection, null);
  109. }
  110. @Override
  111. public List<String> find(String collectionName, String filter, String projection, String options) {
  112. MongoCollection<Document> collection = getCollection(collectionName);
  113. Document filterDocument = new Document();
  114. if (filter != null) {
  115. filterDocument = Document.parse(filter);
  116. }
  117. Document projectionDocument = new Document();
  118. if (projection != null) {
  119. projectionDocument = Document.parse(projection);
  120. }
  121. FindIterable<Document> documents = collection.find(filterDocument).projection(projectionDocument);
  122. List<String> list = new ArrayList<>();
  123. try (MongoCursor<Document> cursor = documents.iterator()) {
  124. while (cursor.hasNext()) {
  125. Document doc = cursor.next();
  126. list.add(doc.toJson());
  127. }
  128. }
  129. return list;
  130. }
  131. // @Override
  132. // public List<String> aggregate(String collectionName, List<? extends String> pipeline) {
  133. // return null;
  134. // }
  135. // @Override
  136. // public List<String> mapReduce(String collectionName, String mapFunction, String reduceFunction) {
  137. // return null;
  138. // }
  139. @Override
  140. public void insertOne(String collectionName, String document) {
  141. MongoCollection<Document> collection = getCollection(collectionName);
  142. Document doc = Document.parse(document);
  143. collection.insertOne(doc);
  144. }
  145. @Override
  146. public void insertMany(String collectionName, List<String> documents) {
  147. insertMany(collectionName, documents, null);
  148. }
  149. /**
  150. * @param collectionName
  151. * @param documents the documents to insert
  152. * @param options the options to apply to the operation
  153. * {
  154. * orderd:<orderd>
  155. * }
  156. */
  157. @Override
  158. public void insertMany(String collectionName, List<String> documents, String options) {
  159. MongoCollection<Document> collection = getCollection(collectionName);
  160. List<Document> list = new ArrayList<>();
  161. for (String document : documents) {
  162. Document doc = Document.parse(document);
  163. list.add(doc);
  164. }
  165. InsertManyOptions insertManyOptions = new InsertManyOptions();
  166. if (options != null) {
  167. ObjectMapper mapper = new ObjectMapper();
  168. try {
  169. JsonNode rootNode = mapper.readValue(options, JsonNode.class);
  170. insertManyOptions.ordered(rootNode.path("ordered").asBoolean());
  171. } catch (IOException e) {
  172. e.printStackTrace();
  173. }
  174. }
  175. collection.insertMany(list, insertManyOptions);
  176. }
  177. @Override
  178. public long deleteOne(String collectionName, String filter) {
  179. MongoCollection<Document> collection = getCollection(collectionName);
  180. Document filterDocument = Document.parse(filter);
  181. DeleteResult deleteResult = collection.deleteOne(filterDocument);
  182. return deleteResult.getDeletedCount();
  183. }
  184. @Override
  185. public long deleteMany(String collectionName, String filter) {
  186. MongoCollection<Document> collection = getCollection(collectionName);
  187. Document filterDocument = Document.parse(filter);
  188. DeleteResult deleteResult = collection.deleteMany(filterDocument);
  189. return deleteResult.getDeletedCount();
  190. }
  191. @Override
  192. public long replaceOne(String collectionName, String filter, String replacement) {
  193. return replaceOne(collectionName, filter, replacement, null);
  194. }
  195. /**
  196. * @param collectionName
  197. * @param filter the query filter to apply the the replace operation
  198. * @param replacement the replacement document
  199. * @param updateOptions the options to apply to the replace operation
  200. * {
  201. * upsert:<upsert>
  202. * }
  203. * @return
  204. */
  205. @Override
  206. public long replaceOne(String collectionName, String filter, String replacement, String updateOptions) {
  207. MongoCollection<Document> collection = getCollection(collectionName);
  208. Document filterDocument = Document.parse(filter);
  209. Document document = Document.parse(replacement);
  210. UpdateOptions options = new UpdateOptions();
  211. if (updateOptions != null) {
  212. ObjectMapper mapper = new ObjectMapper();
  213. try {
  214. JsonNode rootNode = mapper.readValue(updateOptions, JsonNode.class);
  215. options.upsert(rootNode.path("upsert").asBoolean());
  216. } catch (IOException e) {
  217. e.printStackTrace();
  218. }
  219. }
  220. UpdateResult updateResult = collection.replaceOne(filterDocument, document, options);
  221. return updateResult.getModifiedCount();
  222. }
  223. @Override
  224. public long updateOne(String collectionName, String filter, String update) {
  225. return updateOne(collectionName, filter, update, null);
  226. }
  227. /**
  228. * @param collectionName
  229. * @param filter a document describing the query filter, which may not be null.
  230. * @param update a document describing the update, which may not be null. The update to apply must include only update operators.
  231. * @param updateOptions the options to apply to the update operation
  232. * {
  233. * upsert:<upsert>
  234. * }
  235. * @return
  236. */
  237. @Override
  238. public long updateOne(String collectionName, String filter, String update, String updateOptions) {
  239. MongoCollection<Document> collection = getCollection(collectionName);
  240. Document filterDocument = Document.parse(filter);
  241. Document document = Document.parse(update);
  242. UpdateOptions options = new UpdateOptions();
  243. if (updateOptions != null) {
  244. ObjectMapper mapper = new ObjectMapper();
  245. try {
  246. JsonNode rootNode = mapper.readValue(updateOptions, JsonNode.class);
  247. options.upsert(rootNode.path("upsert").asBoolean());
  248. } catch (IOException e) {
  249. e.printStackTrace();
  250. }
  251. }
  252. UpdateResult updateResult = collection.updateOne(filterDocument, document, options);
  253. return updateResult.getModifiedCount();
  254. }
  255. @Override
  256. public long updateMany(String collectionName, String filter, String update) {
  257. return updateMany(collectionName, filter, update, null);
  258. }
  259. /**
  260. * @param collectionName
  261. * @param filter a document describing the query filter, which may not be null.
  262. * @param update a document describing the update, which may not be null. The update to apply must include only update operators.
  263. * @param updateOptions the options to apply to the update operation
  264. * {
  265. * upsert:<upsert>
  266. * }
  267. * @return
  268. */
  269. @Override
  270. public long updateMany(String collectionName, String filter, String update, String updateOptions) {
  271. MongoCollection<Document> collection = getCollection(collectionName);
  272. Document filterDocument = Document.parse(filter);
  273. Document document = Document.parse(update);
  274. UpdateOptions options = new UpdateOptions();
  275. if (updateOptions != null) {
  276. ObjectMapper mapper = new ObjectMapper();
  277. try {
  278. JsonNode rootNode = mapper.readValue(updateOptions, JsonNode.class);
  279. options.upsert(rootNode.path("upsert").asBoolean());
  280. } catch (IOException e) {
  281. e.printStackTrace();
  282. }
  283. }
  284. UpdateResult updateResult = collection.updateMany(filterDocument, document, options);
  285. return updateResult.getModifiedCount();
  286. }
  287. @Override
  288. public String findOneAndDelete(String collectionName, String filter) {
  289. return findOneAndDelete(collectionName, filter, null);
  290. }
  291. /**
  292. * @param collectionName
  293. * @param filter the query filter to find the document with
  294. * @param options the options to apply to the operation
  295. * {
  296. * projection:<document>,
  297. * sort:<document>
  298. * }
  299. * @return
  300. */
  301. @Override
  302. public String findOneAndDelete(String collectionName, String filter, String options) {
  303. MongoCollection<Document> collection = getCollection(collectionName);
  304. Document filterDocument = Document.parse(filter);
  305. FindOneAndDeleteOptions findOneAndDeleteOptions = new FindOneAndDeleteOptions();
  306. if (options != null) {
  307. ObjectMapper mapper = new ObjectMapper();
  308. try {
  309. JsonNode rootNode = mapper.readValue(options, JsonNode.class);
  310. String projection = rootNode.path("projection").toString();
  311. Document projectionDoc = new Document();
  312. if (!StringUtils.isEmpty(projection)) {
  313. Document.parse(projection);
  314. }
  315. String sort = rootNode.path("sort").toString();
  316. Document sortDoc = new Document();
  317. if (!StringUtils.isEmpty(sort)) {
  318. Document.parse(sort);
  319. }
  320. findOneAndDeleteOptions.projection(projectionDoc);
  321. findOneAndDeleteOptions.sort(sortDoc);
  322. } catch (IOException e) {
  323. e.printStackTrace();
  324. }
  325. }
  326. Document document = collection.findOneAndDelete(filterDocument, findOneAndDeleteOptions);
  327. return document == null ? "{}" : document.toJson();
  328. }
  329. @Override
  330. public String findOneAndReplace(String collectionName, String filter, String replacement) {
  331. return findOneAndReplace(collectionName, filter, replacement, null);
  332. }
  333. /**
  334. * @param collectionName
  335. * @param filter the query filter to apply the the replace operation
  336. * @param replacement the replacement document
  337. * @param options the options to apply to the operation
  338. * {
  339. * projection:<document>,
  340. * sort:<document>,
  341. * upsert:<upsert>
  342. * }
  343. * @return
  344. */
  345. @Override
  346. public String findOneAndReplace(String collectionName, String filter, String replacement, String options) {
  347. MongoCollection<Document> collection = getCollection(collectionName);
  348. Document filterDocument = Document.parse(filter);
  349. Document replacementDocument = Document.parse(replacement);
  350. FindOneAndReplaceOptions findOneAndReplaceOptions = new FindOneAndReplaceOptions();
  351. if (options != null) {
  352. ObjectMapper mapper = new ObjectMapper();
  353. try {
  354. JsonNode rootNode = mapper.readValue(options, JsonNode.class);
  355. String projection = rootNode.path("projection").toString();
  356. Document projectionDoc = new Document();
  357. if (!StringUtils.isEmpty(projection)) {
  358. Document.parse(projection);
  359. }
  360. String sort = rootNode.path("sort").toString();
  361. Document sortDoc = new Document();
  362. if (!StringUtils.isEmpty(sort)) {
  363. Document.parse(sort);
  364. }
  365. findOneAndReplaceOptions.projection(projectionDoc);
  366. findOneAndReplaceOptions.sort(sortDoc);
  367. findOneAndReplaceOptions.upsert(rootNode.path("upsert").asBoolean());
  368. } catch (IOException e) {
  369. e.printStackTrace();
  370. }
  371. }
  372. Document document = collection.findOneAndReplace(filterDocument, replacementDocument, findOneAndReplaceOptions);
  373. return document == null ? "{}" : document.toJson();
  374. }
  375. @Override
  376. public String findOneAndUpdate(String collectionName, String filter, String update) {
  377. return findOneAndUpdate(collectionName, filter, update, null);
  378. }
  379. /**
  380. * @param collectionName
  381. * @param filter a document describing the query filter, which may not be null.
  382. * @param update a document describing the update, which may not be null. The update to apply must include only update operators.
  383. * @param options the options to apply to the operation
  384. * {
  385. * projection:<document>,
  386. * sort:<document>,
  387. * upsert:<upsert>
  388. * }
  389. * @return
  390. */
  391. @Override
  392. public String findOneAndUpdate(String collectionName, String filter, String update, String options) {
  393. MongoCollection<Document> collection = getCollection(collectionName);
  394. Document filterDocument = Document.parse(filter);
  395. Document updateDocument = Document.parse(update);
  396. FindOneAndUpdateOptions findOneAndUpdateOptions = new FindOneAndUpdateOptions();
  397. if (options != null) {
  398. ObjectMapper mapper = new ObjectMapper();
  399. try {
  400. JsonNode rootNode = mapper.readValue(options, JsonNode.class);
  401. String projection = rootNode.path("projection").asText();
  402. Document projectionDoc = Document.parse(projection);
  403. String sort = rootNode.path("sort").asText();
  404. Document sortDoc = Document.parse(sort);
  405. findOneAndUpdateOptions.projection(projectionDoc);
  406. findOneAndUpdateOptions.sort(sortDoc);
  407. findOneAndUpdateOptions.upsert(rootNode.path("upsert").asBoolean());
  408. } catch (IOException e) {
  409. e.printStackTrace();
  410. }
  411. }
  412. Document document = collection.findOneAndUpdate(filterDocument, updateDocument, findOneAndUpdateOptions);
  413. return document.toJson();
  414. }
  415. @Override
  416. public void drop(String collectionName) {
  417. getCollection(collectionName).drop();
  418. }
  419. @Override
  420. public String createIndex(String collectionName, String keys) {
  421. MongoCollection<Document> collection = getCollection(collectionName);
  422. Document keysDocument = Document.parse(keys);
  423. return collection.createIndex(keysDocument);
  424. }
  425. @Override
  426. public String createIndex(String collectionName, String keys, String indexOptions) {
  427. MongoCollection<Document> collection = getCollection(collectionName);
  428. Document keysDocument = Document.parse(keys);
  429. IndexOptions options = new IndexOptions();
  430. //TODO:解析indexOptions
  431. // try {
  432. // ObjectMapper mapper = new ObjectMapper();
  433. // JsonNode rootNode = mapper.readValue(indexOptions, JsonNode.class);
  434. //
  435. //
  436. // } catch (IOException e) {
  437. // e.printStackTrace();
  438. // }
  439. return collection.createIndex(keysDocument, options);
  440. }
  441. @Override
  442. public List<String> listIndexes(String collectionName) {
  443. MongoCollection<Document> collection = getCollection(collectionName);
  444. ListIndexesIterable<Document> indexes = collection.listIndexes();
  445. List<String> list = new ArrayList<>();
  446. try (MongoCursor<Document> cursor = indexes.iterator()) {
  447. while (cursor.hasNext()) {
  448. Document doc = cursor.next();
  449. list.add(doc.toJson());
  450. }
  451. }
  452. return list;
  453. }
  454. @Override
  455. public void dropIndex(String collectionName, String indexName) {
  456. getCollection(collectionName).dropIndex(indexName);
  457. }
  458. @Override
  459. public void dropIndexes(String collectionName) {
  460. getCollection(collectionName).dropIndexes();
  461. }
  462. @Override
  463. public void renameCollection(String collectionName, String newCollectionName) {
  464. MongoCollection<Document> collection = getCollection(collectionName);
  465. MongoNamespace namespace = collection.getNamespace();
  466. collection.renameCollection(new MongoNamespace(namespace.getDatabaseName(), newCollectionName));
  467. }
  468. @Override
  469. public void renameCollection(String collectionName, String newCollectionName, String renameCollectionOptions) {
  470. MongoCollection<Document> collection = getCollection(collectionName);
  471. MongoNamespace namespace = collection.getNamespace();
  472. RenameCollectionOptions options = new RenameCollectionOptions();
  473. try {
  474. ObjectMapper mapper = new ObjectMapper();
  475. JsonNode rootNode = mapper.readValue(renameCollectionOptions, JsonNode.class);
  476. options.dropTarget(rootNode.path("dropTarget").asBoolean());
  477. } catch (IOException e) {
  478. e.printStackTrace();
  479. }
  480. collection.renameCollection(new MongoNamespace(namespace.getDatabaseName(), newCollectionName), options);
  481. }
  482. public MongoCollection<Document> getCollection(String collectionName) {
  483. MongoDatabase database = config.getDatabase();
  484. return database.getCollection(collectionName);
  485. }
  486. public List<String> listCollectionNames() {
  487. MongoDatabase database = config.getDatabase();
  488. MongoIterable<String> listCollectionNames = database.listCollectionNames();
  489. List<String> list = new ArrayList<>();
  490. for (String collectionName : listCollectionNames) {
  491. list.add(collectionName);
  492. }
  493. return list;
  494. }
  495. }