{"id":280116,"date":"2016-10-28T20:00:02","date_gmt":"2016-10-28T16:00:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=280116"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=280116","title":{"rendered":"\u041a\u0430\u043a \u043f\u043e\u0434\u0440\u0443\u0436\u0438\u0442\u044c Bagri \u0438 MongoDB"},"content":{"rendered":"<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043c\u0435\u0441\u044f\u0446 \u043d\u0430\u0437\u0430\u0434, \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u0425\u0430\u0431\u0440\u0443 \u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0435 <a href=\"http:\/\/bagridb.com\">Bagri<\/a>: <a href=\"https:\/\/habrahabr.ru\/post\/310110\/\">NoSQL \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u0432\u0435\u0440\u0445 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0430<\/a>. <\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0433\u043e \u043e\u0442\u043a\u043b\u0438\u043a\u0430, \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b Bagri \u043f\u0443\u0442\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 (extensions) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 API \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d4d\/303\/3f2\/d4d3033f2ce94acdb3111b5c320b05eb.png\" alt=\"image\"\/><\/p>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 Bagri \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u0434\u0432\u0430 API \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c: DataFormat API \u0438 DataStore API. <\/p>\n<p>  \u041f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043d\u043e\u0432\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0445 \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043d\u043e\u0432\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0438\u0437 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b. <\/p>\n<p>  \u0412\u0442\u043e\u0440\u043e\u0439 API \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438\/\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f. \u0417\u0430\u0447\u0430\u0441\u0442\u0443\u044e, \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u043d\u043e\u0432\u043e\u043c\u0443 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0443 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. <\/p>\n<p>  \u042f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c DataStore connector \u043a MongoDB \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 DataFormat API \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 Mongo \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u0432 JSON \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439.<\/p>\n<p>  \u0421\u0440\u0430\u0437\u0443 \u0445\u043e\u0447\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0439:<\/p>\n<ol>\n<li>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u043e\u043b\u044c\u0437\u0430 \u043e\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430? \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, Mongo \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0422\u0430\u043a \u0436\u0435 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0432 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432 <a href=\"http:\/\/www.sarahmei.com\/blog\/2013\/11\/11\/why-you-should-never-use-mongodb\/\">\u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>, \u043a\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0436\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 Mongo, \u043d\u043e \u0435\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0441\u0442\u0430\u043b\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b;<\/li>\n<li>\u042f \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0441\u044c \u0437\u043d\u0430\u0442\u043e\u043a\u043e\u043c MongoDB, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0435\u0439, \u044f \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u0438\u0445 \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c;<\/li>\n<\/ol>\n<p>  \u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c.<\/p>\n<p>  DataStore API \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 com.bagri.xdm.cache.api.DocumentStore:<\/p>\n<pre><code class=\"java\">public interface DocumentStore { \t         \/**          * Lifecycle method. Invoked when the store initialized.           *           * @param context the environment context          *\/         void init(Map&lt;String, Object&gt; context); \t         \/**          * Lifecycle method. Invoked when parent schema is closing          *\/         void close();          \/**          * Load document from persistent store          *           * @param key the document key          * @return XDM Document instance if corresponding document found, null otherwise          *\/         Document loadDocument(DocumentKey key);          \/**          * Load bunch of documents from persistent store          *           * @param keys the collection of document keys to load          * @return the map of loaded documents with their keys          *\/         Map&lt;DocumentKey, Document&gt; loadAllDocuments(Collection&lt;DocumentKey&gt; keys);          \/**          * Load document keys. Can do it in synch or asynch way.          *           * @return iterator over found document keys          *\/         Iterable&lt;DocumentKey&gt; loadAllDocumentKeys();          \/**          * Stores document to persistent store.          *           * @param key the document key          * @param value the XDM document instance          *\/         void storeDocument(DocumentKey key, Document value);          \/**          * Stores bunch of documents to persistent store          *           * @param entries the map of document keys and corresponding document instances          *\/         void storeAllDocuments(Map&lt;DocumentKey, Document&gt; entries);          \/**          * Deletes document from persistent store          *           * @param key the document key          *\/         void deleteDocument(DocumentKey key);          \/**          * Deletes bunch o documents from persistent store           *           * @param keys the keys identifying documents to be deleted           *\/         void deleteAllDocuments(Collection&lt;DocumentKey&gt; keys); \t\t } <\/code><\/pre>\n<p>  \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 DocumentStore, \u043e\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 DocumentStoreBase, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0438 \u0435\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. <\/p>\n<p>  \u0414\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a Mongo \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 mongod, \u0438\u043c\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u043c\u0435\u043d\u0430 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0438\u043c\u0435\u043d\u0430 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432: mongo.db.uri, mongo.db.database, mongo.db.collections. \u0422\u043e\u0433\u0434\u0430 \u043a\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 mongo \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">public class MongoDBStore extends DocumentStoreBase implements DocumentStore { \t         private MongoClient client;         private MongoDatabase db;         private Map&lt;String, MongoCollection&lt;org.bson.Document&gt;&gt; clMap = new HashMap&lt;&gt;(); \t         @Override         public void init(Map&lt;String, Object&gt; context) { \t    super.setContext(context); \t    String uri = (String) context.get(&quot;mongo.db.uri&quot;);  \t    MongoClientURI mcUri = new MongoClientURI(uri); \t    client = new MongoClient(mcUri);  \t    String dbName = (String) context.get(&quot;mongo.db.database&quot;); \t    db = client.getDatabase(dbName); \t\t \t    String clNames = (String) context.get(&quot;mongo.db.collections&quot;); \t    boolean all = &quot;*&quot;.equals(clNames); \t    List&lt;String&gt; clns = Arrays.asList(clNames.split(&quot;,&quot;)); \t    for (String clName: db.listCollectionNames()) { \t\tif (all || clns.contains(clName)) { \t\t    MongoCollection&lt;org.bson.Document&gt; cln = db.getCollection(clName);  \t\t    clMap.put(clName, cln); \t\t} \t    }         }          @Override         public void close() {                 client.close();         } } <\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 init \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 mongod \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 MongoCollection \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u0435\u0445 \u043a\u043b\u044e\u0447\u0435\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<pre><code class=\"java\">        private String getMappingKey(String id, String cln) { \t      return id + &quot;::&quot; + cln;         } \t         private String[] getMappingParts(String keyMap) { \t      return keyMap.split(&quot;::&quot;);         }          @Override         public Iterable&lt;DocumentKey&gt; loadAllDocumentKeys() { \t    SchemaRepository repo = getRepository();             if (repo == null) { \t\treturn null; \t    }  \t    String id; \t    DocumentKey key; \t    Map&lt;DocumentKey, String&gt; keyMap = new HashMap&lt;&gt;(); \t    for (MongoCollection&lt;org.bson.Document&gt; cln: clMap.values()) { \t\tString clName = cln.getNamespace().getCollectionName(); \t\t\/\/ load _ids only \t\tMongoCursor&lt;org.bson.Document&gt; cursor =   cln.find().projection(include(\u201c_id\u201d)).iterator(); \t\t                 while (cursor.hasNext()) { \t\t      org.bson.Document doc = cursor.next(); \t\t      id = doc.get(\u201c_id\u201d).toString(); \t\t      \/\/ TODO: handle possible duplicates via revisions \t\t      key = repo.getFactory().newDocumentKey(id, 0, 1); \t\t      keyMap.put(key, getMappingKey(id, clName)); \t\t} \t    }    \t    PopulationManagement popManager = repo.getPopulationManagement();    \t    popManager.setKeyMappings(keyMap); \t    return keyMap.keySet();         } <\/code><\/pre>\n<p>  \u0418 \u043c\u0435\u0442\u043e\u0434\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u0430\u043c:<\/p>\n<pre><code class=\"java\">       @Override         public Map&lt;DocumentKey, Document&gt; loadAllDocuments(Collection&lt;DocumentKey&gt; keys) { \t    Map&lt;DocumentKey, Document&gt; entries = new HashMap&lt;&gt;(keys.size()); \t    for (DocumentKey key: keys) { \t\tDocument doc = loadDocument(key); \t\tif (doc != null) { \t\t      entries.put(key, doc); \t\t} \t    } \t    return entries;         }          @Override         public Document loadDocument(DocumentKey key) {           SchemaRepository repo = getRepository();     \t  Document doc = null; \t    \t  PopulationManagement popManager = repo.getPopulationManagement();      \t  String id = popManager.getKeyMapping(key);      \t  if (id == null) { \t      return null;     \t  }     \t  String[] mParts = getMappingParts(id); \t  Document newDoc = null;      \t  int[] clns = null;     \t  com.bagri.xdm.system.Collection xcl = repo.getSchema().getCollection(mParts[1]);     \t  if (xcl != null) {     \t        clns = new int[] {xcl.getId()};     \t  }     \t  MongoCollection&lt;org.bson.Document&gt; cln = clMap.get(mParts[1]);  \t  Object oid;     \t  Date creDate;     \t  try {     \t        oid = new ObjectId(mParts[0]);     \t        creDate = ((ObjectId) oid).getDate();     \t  } catch (IllegalArgumentException ex) { \t        oid = mParts[0];     \t        creDate = new Date();     \t  } \t  org.bson.Document mongoDoc = cln.find(eq(&quot;_id&quot;, oid)).first(); \t  String content = mongoDoc.toJson(new JsonWriterSettings(true));     \t  try {        \t        DocumentManagementl docMgr = (DocumentManagement) repo.getDocumentManagement();  \t        newDoc = docMgr.createDocument(key, mParts[0], content, \u201cJSON\u201d, creDate, &quot;owner&quot;, 1, clns, true); \t  } catch (XDMException ex) { \t        \/\/ TODO: log error, but do not stop the whole loading \t  } \t  return doc;       } <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043c\u0435\u0442\u043e\u0434\u044b storeDocument\/storeAllDocuments \u0438 deleteDocument\/deleteAllDocuments \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0448\u0443 \u0443\u0447\u0435\u0441\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u043a\u043e\u0434 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0446\u0435\u043b\u044f\u0445 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u0438 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f <a href=\"https:\/\/github.com\/dsukhoroslov\/bagri-extensions\">bagri-extensions<\/a>.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c DataStore connector \u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0441\u0445\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u0432 \u0444\u0430\u0439\u043b &lt;BAGRI_HOME&gt;\/config\/config.xml, \u0432 \u0441\u0435\u043a\u0446\u0438\u044e dataStores:<\/p>\n<pre><code class=\"java\">&lt;dataStore name=&quot;mongo&quot;&gt;     &lt;version&gt;1&lt;\/version&gt;     &lt;createdAt&gt;2016-08-01T16:17:20.542+03:00&lt;\/createdAt&gt;     &lt;createdBy&gt;admin&lt;\/createdBy&gt;     &lt;description&gt;MongoDB data store&lt;\/description&gt;     &lt;enabled&gt;true&lt;\/enabled&gt;     &lt;storeClass&gt;com.bagri.samples.MongoDBStore&lt;\/storeClass&gt;     &lt;properties&gt;         &lt;entry name=&quot;mongo.db.uri&quot;&gt;mongodb:\/\/localhost:27017&lt;\/entry&gt;         &lt;entry name=&quot;mongo.db.database&quot;&gt;test&lt;\/entry&gt;         &lt;entry name=&quot;mongo.db.collections&quot;&gt;*&lt;\/entry&gt;      &lt;\/properties&gt; &lt;\/dataStore&gt; <\/code><\/pre>\n<p>  \u041c\u044b \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 restaurants, \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 MongoDB. \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 Mongo, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/docs.mongodb.com\/getting-started\/shell\/import-data\/\">docs.mongodb.com\/getting-started\/shell\/import-data<\/a>. \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 MongoDB \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0435\u0435 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u0412 \u0442\u043e\u043c \u0436\u0435 \u0444\u0430\u0439\u043b\u0435 config.xml \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b schemas:<\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:<\/p>\n<pre><code class=\"xml\">&lt;entry name=&quot;xdm.schema.store.enabled&quot;&gt;true&lt;\/entry&gt; &lt;entry name=&quot;xdm.schema.store.type&quot;&gt;mongo&lt;\/entry&gt; &lt;entry name=&quot;mongo.db.collections&quot;&gt;restaurants&lt;\/entry&gt; <\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0420\u0430\u0437\u0434\u0435\u043b schemas \u0432 config.xml \u0441 \u043d\u043e\u0432\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">&lt;schema name=&quot;Mongo&quot; active=&quot;true&quot;&gt;             &lt;version&gt;1&lt;\/version&gt;             &lt;createdAt&gt;2016-08-01T21:30:58.096+04:00&lt;\/createdAt&gt;             &lt;createdBy&gt;admin&lt;\/createdBy&gt;             &lt;description&gt;Schema for MongoDB&lt;\/description&gt;             &lt;properties&gt;                 &lt;entry name=&quot;xdm.schema.store.tx.buffer.size&quot;&gt;1024&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.data.backup.read&quot;&gt;false&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.trans.backup.async&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.store.enabled&quot;&gt;true&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.thread.pool&quot;&gt;10&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.data.stats.enabled&quot;&gt;true&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.query.cache&quot;&gt;true&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.store.type&quot;&gt;mongo&lt;\/entry&gt;                 &lt;entry name=&quot;mongo.db.collections&quot;&gt;restaurants&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.format.default&quot;&gt;JSON&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.ports.first&quot;&gt;10300&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.ports.last&quot;&gt;10400&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.population.size&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.population.buffer.size&quot;&gt;1000000&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.data.backup.async&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.store.data.path&quot;&gt;..\/data\/mongo&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.dict.backup.sync&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.trans.backup.sync&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.query.backup.sync&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.buffer.size&quot;&gt;16&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.dict.backup.async&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.dict.backup.read&quot;&gt;true&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.trans.backup.read&quot;&gt;false&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.query.backup.async&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.members&quot;&gt;localhost&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.data.backup.sync&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.partition.count&quot;&gt;157&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.query.backup.read&quot;&gt;true&lt;\/entry&gt; \t        &lt;entry name=&quot;xdm.schema.transaction.timeout&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.health.threshold.low&quot;&gt;25&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.health.threshold.high&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.query.parallel&quot;&gt;true&lt;\/entry&gt;                 &lt;entry name=&quot;xdm.schema.partition.pool&quot;&gt;32&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.baseUri&quot;&gt;file:\/\/\/..\/data\/mongo\/&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.orderingMode&quot;&gt;2&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.queryLanguageTypeAndVersion&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.bindingMode&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.boundarySpacePolicy&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.scrollability&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.holdability&quot;&gt;2&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.copyNamespacesModePreserve&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.queryTimeout&quot;&gt;0&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.defaultFunctionNamespace&quot;&gt;&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.defaultElementTypeNamespace&quot;&gt;&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.copyNamespacesModeInherit&quot;&gt;1&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.defaultOrderForEmptySequences&quot;&gt;2&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.defaultCollationUri&quot;&gt;&lt;\/entry&gt;                 &lt;entry name=&quot;xqj.schema.constructionMode&quot;&gt;1&lt;\/entry&gt;             &lt;\/properties&gt;             &lt;collections&gt;                 &lt;collection id=&quot;1&quot; name=&quot;restaurants&quot;&gt;                     &lt;version&gt;1&lt;\/version&gt;                     &lt;createdAt&gt;2016-08-01T01:01:26.965+03:00&lt;\/createdAt&gt;                     &lt;createdBy&gt;admin&lt;\/createdBy&gt;                     &lt;description&gt;Mongo restaurants collection&lt;\/description&gt;                     &lt;enabled&gt;true&lt;\/enabled&gt;                 &lt;\/collection&gt;             &lt;\/collections&gt;             &lt;fragments\/&gt;             &lt;indexes\/&gt;             &lt;triggers\/&gt;         &lt;\/schema&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u0441 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0412 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 &lt;BAGRI_HOME&gt;\/config \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b mongo.properties \u0438 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0432 \u043d\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0443\u044e \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0441\u0445\u0435\u043c\u0443:<\/p>\n<pre><code class=\"xml\">xdm.cluster.node.schemas=Mongo <\/code><\/pre>\n<p>  \u0423\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044c\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440 MongoDB \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0438 \u0436\u0434\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 Bagri. \u0412 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 &lt;BAGRI_HOME&gt;\/bin \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 &gt;bgcache.cmd mongo (on Windows) \u0438\u043b\u0438 &gt;.\/bgcache.sh mongo (on Linux). \u0414\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 Bagri \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0438\u0437 \u043f\u0440\u043e\u0444\u0438\u043b\u044f mongo.properties. \u041f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043b\u043e\u0433 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u0447\u043a\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/bd8\/d6f\/b94\/bd8d6fb949254d519665b5c43a06f3b4.png\" alt=\"image\"\/><\/p>\n<p>  \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0435, \u0447\u0442\u043e \u0432 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0441\u0445\u0435\u043c\u0443 Mongo \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b \u0432 \u043d\u0435\u0435 25359 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 MongoDB.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 JSON \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 XQuery.<\/p>\n<p>  \u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 XQuery \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c. \u0421 \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0432\u043e\u043c Bagri \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f plugin \u043a VisualVM, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043f\u043e \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 <a href=\"http:\/\/bagridb.com\/wp-content\/uploads\/2016\/05\/Installation-and-Configuration-Guide.pdf\">\u0437\u0434\u0435\u0441\u044c<\/a>. <\/p>\n<p>  \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 Bagri &lt;BAGRI_HOME&gt;\/bin\/bgadmin. \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 VisualVM, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u0441\u044c \u043a \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 Bagri Manager \u0438 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0445\u0435\u043c\u0443 Mongo. \u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0430 DocumentManagement \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/894\/526\/d54\/894526d54d764b91920fac57482a5682.png\" alt=\"image\"\/><\/p>\n<p>  , \u0430 \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0430 QueryManagement \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 XQuery. \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0440\u0435\u0441\u0442\u043e\u0440\u0430\u043d\u0430 \u043f\u043e \u0435\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0443:<\/p>\n<pre><code class=\"xml\">declare namespace m=&quot;http:\/\/www.w3.org\/2005\/xpath-functions\/map&quot;;  let $props := map{'method': 'json', 'indent': fn:true()}  for $uri in fn:uri-collection(&quot;restaurants&quot;) let $map := fn:json-doc($uri) where m:get($map, 'restaurant_id') = '40362098' return (fn:serialize($map, $props), '\\&\\#xa;') <\/code><\/pre>\n<p>  * \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0438\u043c\u0432\u043e\u043b \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0441\u0430\u043c\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u044d\u043a\u0440\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d \\, \u0442\u0430\u043a \u043a\u0430\u043a \u0425\u0430\u0431\u0440 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u0438\u043c\u0432\u043e\u043b \\ \u043d\u0443\u0436\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/20c\/50b\/298\/20c50b2987b1427abcd4bc02ebaad8b9.png\" alt=\"image\"\/><\/p>\n<p>  \u0418\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439, \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0440\u0435\u0441\u0442\u043e\u0440\u0430\u043d\u043e\u0432 \u043f\u043e \u0442\u0438\u043f\u0443 \u043a\u0443\u0445\u043d\u0438:<\/p>\n<pre><code class=\"xml\">declare namespace m=&quot;http:\/\/www.w3.org\/2005\/xpath-functions\/map&quot;;  let $props := map{'method': 'json'}  for $uri in fn:uri-collection(&quot;restaurants&quot;) let $map := fn:json-doc($uri) where m:get($map, 'cuisine') = 'Bakery' return (fn:serialize($map, $props), '\\&\\#xa;') <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/c65\/43e\/239\/c6543e23938a4e0f87bc3642490d9928.png\" alt=\"image\"\/><\/p>\n<p>  XQuery \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0432\u044b\u0431\u043e\u0440\u043a\u0438, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432 Mongo (\u043a\u0440\u043e\u043c\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e \u0433\u0435\u043e-\u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c, \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043e\u043d\u0438 \u0435\u0449\u0435 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f). <\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 MongoDB: JOIN. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 restaurants \u043a \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u043c\u0443 \u0432\u0438\u0434\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c \u043e\u0442\u0437\u044b\u0432\u044b \u043e \u0440\u0435\u0441\u0442\u043e\u0440\u0430\u043d\u0430\u0445 \u043e\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0441\u0430\u043c\u043e\u043c\u0443 \u0440\u0435\u0441\u0442\u043e\u0440\u0430\u043d\u0443 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u0445. <\/p>\n<p>  \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u0444\u0430\u0439\u043b, \u043f\u043e\u0442\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0438\u043c\u043f\u043e\u0440\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 MongoDB, \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e rest-short.<\/p>\n<pre><code class=\"xml\">declare namespace m=&quot;http:\/\/www.w3.org\/2005\/xpath-functions\/map&quot;; let $props := map{'method': 'json'}  for $uri in fn:uri-collection(&quot;restaurants&quot;) let $rest := fn:json-doc($uri) let $rest := m:remove($rest, '_id') let $rest := m:remove($rest, 'grades') return (fn:serialize($rest, $props), '\\&\\#xa;') <\/code><\/pre>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u043e\u0442\u0437\u044b\u0432\u0430\u043c. \u0422\u0430\u043a \u0436\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438 \u0437\u0430\u0442\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0432 MongoDB \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e grades.<\/p>\n<pre><code class=\"xml\">declare namespace a=&quot;http:\/\/www.w3.org\/2005\/xpath-functions\/array&quot;; declare namespace m=&quot;http:\/\/www.w3.org\/2005\/xpath-functions\/map&quot;; let $props := map{'method': 'json'}  for $uri in fn:uri-collection(&quot;restaurants&quot;) let $rest := fn:json-doc($uri) let $grades := m:get($rest, 'grades') return    for $i in (1 to a:size($grades))     let $grade := a:get($grades, $i)     let $date := m:get($grade, 'date')     return ('{&quot;restaurant_id&quot;: &quot;', m:get($rest, 'restaurant_id'),  \t'&quot;, &quot;date&quot;: ', fn:serialize($date, $props),  \t ', &quot;grade&quot;: &quot;', m:get($grade, 'grade'),  \t'&quot;, &quot;score&quot;: &quot;', m:get($grade, 'score'), '&quot;}', '\\&\\#xa;') <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0445\u0435\u043c\u044b, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u044f\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:<\/p>\n<pre><code class=\"xml\">&lt;schema name=&quot;Mongo&quot; active=&quot;true&quot;&gt; \t     \u2026\u2026\u2026...             &lt;properties&gt;                 &lt;entry name=&quot;xdm.schema.store.collections&quot;&gt;rest-short, grades&lt;\/entry&gt; \t         \u2026\u2026...             &lt;\/properties&gt;             &lt;collections&gt;                 &lt;collection id=&quot;2&quot; name=&quot;rest-short&quot;&gt;                     &lt;version&gt;1&lt;\/version&gt;                     &lt;createdAt&gt;2016-08-01T01:01:26.965+03:00&lt;\/createdAt&gt;                     &lt;createdBy&gt;admin&lt;\/createdBy&gt;                     &lt;description&gt;Restaurant headers collection&lt;\/description&gt;                     &lt;enabled&gt;true&lt;\/enabled&gt;                 &lt;\/collection&gt;                 &lt;collection id=&quot;3&quot; name=&quot;grades&quot;&gt;                     &lt;version&gt;1&lt;\/version&gt;                     &lt;createdAt&gt;2016-08-01T01:01:26.965+03:00&lt;\/createdAt&gt;                     &lt;createdBy&gt;admin&lt;\/createdBy&gt;                     &lt;description&gt;Restaurant grades collection&lt;\/description&gt;                     &lt;enabled&gt;true&lt;\/enabled&gt;                 &lt;\/collection&gt;             &lt;\/collections&gt;             &lt;fragments\/&gt;             &lt;indexes\/&gt;             &lt;triggers\/&gt; &lt;\/schema&gt; <\/code><\/pre>\n<p>  \u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0443\u0439\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 Bagri \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 join\u2019\u044b. \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b restaurants \u0438\u0437 \u0434\u0432\u0443\u0445 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"xml\">declare namespace m=&quot;http:\/\/www.w3.org\/2005\/xpath-functions\/map&quot;; let $props := map{'method': 'json'}  for $ruri in fn:uri-collection(&quot;rest-short&quot;) let $rest := fn:json-doc($ruri) let $rid := m:get($rest, 'restaurant_id') let $addr := m:get($rest, 'address') let $txt := ('{&quot;restaurant_id&quot;: &quot;', $rid, \t'&quot;, &quot;cuisine&quot;: &quot;', m:get($rest, 'cuisine'),  \t'&quot;, &quot;name&quot;: &quot;', m:get($rest, 'name'),  \t'&quot;, &quot;borough&quot;: &quot;', m:get($rest, 'borough'),  \t'&quot;, &quot;address&quot;: ', fn:serialize($addr, $props), \t', &quot;grades&quot;: [') return ($txt, fn:string-join(   for $guri in fn:uri-collection(&quot;grades&quot;)   let $grade := fn:json-doc($guri)   let $gid := m:get($grade, 'restaurant_id')   where $gid = $rid   return fn:serialize(m:remove(m:remove($grade, '_id'), 'restaurant_id'), $props), ', '), ']}\\&\\#xa;') <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c DataStore connector \u043a MongoDB \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0441\u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u0430\u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0411\u0430\u0433\u0440\u0438 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0431\u0443\u0434\u0438\u0442 \u0432\u0430\u0441 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c. \u041f\u0440\u043e\u0435\u043a\u0442\u0443 \u0432\u0441\u0435\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f Java \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u043a\u0438 \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0438 Bagri, \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0430 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/dsukhoroslov\/bagri\">\u0413\u0438\u0442\u0445\u0430\u0431\u0435<\/a>.<br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/312626\/\"> https:\/\/habrahabr.ru\/post\/312626\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043c\u0435\u0441\u044f\u0446 \u043d\u0430\u0437\u0430\u0434, \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u0425\u0430\u0431\u0440\u0443 \u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0435 <a href=\"http:\/\/bagridb.com\">Bagri<\/a>: <a href=\"https:\/\/habrahabr.ru\/post\/310110\/\">NoSQL \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u0432\u0435\u0440\u0445 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0430<\/a>. <\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0433\u043e \u043e\u0442\u043a\u043b\u0438\u043a\u0430, \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b Bagri \u043f\u0443\u0442\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 (extensions) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 API \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d4d\/303\/3f2\/d4d3033f2ce94acdb3111b5c320b05eb.png\" alt=\"image\"\/><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-280116","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/280116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=280116"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/280116\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=280116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=280116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=280116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}