MongoDB Basic
Key takeaways
MongoDbPersistence | Pip.Services component used to create MongoDB persistence objects that accept any type of data. |
IdentifiableMongoDbPersistence | Pip.Services component used to create MongoDB persistence objects that accept identifiable data objects. |
Introduction
This tutorial will help you understand how to create persistence components for MongoDB. In particular, you will learn how to use two components, namely MongoDbPersistence and IdentifiableMongoDbPersistence. The explanations will include practical examples.
Persisting data with MongoDB
The Pip.Services toolkit provides two different components for MongoDB persistence. They are the MongoDbPersistence and the IdentifiableMongoDbPersistence classes respectively. The first can be used to persist objects of any type. The second is aimed at data items with unique ids. Both classes are part of the MongoDB module, persistence
General pre-requisites
In order to use any of these two components, we need to install the MongoDB module. This can be done with the following command:
npm install pip-services3-mongodb-nodex --save
dotnet add package PipServices3.Mongodb
go get -u github.com/pip-services3-gox/pip-services3-mongodb-gox@latest
dart pub add pip_services3_mongodb
pip install pip-services3-mongodb
Data object
Throughout the examples, we will use the data structure that appears below. It contains an id field, which can be used to identify each document. The next two fields (key and content) are generic and represent any type of content that we want to persist.
import { IStringIdentifiable } from 'pip-services3-commons-nodex';
export class MyData implements IStringIdentifiable {
public id: string;
public key: string;
public content: string;
}
using System.Runtime.Serialization;
using PipServices3.Commons.Data;
using MongoDB.Bson.Serialization.Attributes;
[DataContract]
[BsonNoId]
[BsonIgnoreExtraElements]
public class MyData : IStringIdentifiable
{
[BsonElement("id")]
[DataMember(Name = "id")]
public string Id { get; set; }
[BsonElement("key")]
[DataMember(Name = "key")]
public string Key { get; set; }
[BsonElement("content")]
[DataMember(Name = "content")]
public string Content { get; set; }
}
type MyData struct {
Id string `bson:"_id" json:"id"`
Key string `bson:"key" json:"key"`
Content string `bson:"content" json:"content"`
}
type MyDataPage struct {
Total *int64 `bson:"total" json:"total"`
Data []MyData `bson:"data" json:"data"`
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyData implements IStringIdentifiable, ICloneable {
@override
String? id;
String? key;
String? content;
MyData();
MyData.from(this.id, this.key, this.content);
Map<String, dynamic> toJson() {
return <String, dynamic>{'id': id, 'key': key, 'content': content};
}
void fromJson(Map<String, dynamic> json) {
id = json['id'];
key = json['key'];
content = json['content'];
}
@override
MyData clone() {
return MyData.from(id, key, content);
}
}
from pip_services3_commons.data import IStringIdentifiable
class MyData(IStringIdentifiable):
def __init__(self, id: str = None, key: str = None, content: str = None):
self.id = id
self.key = key
self.content = content
In addition, we create three instances of this class, which we will use in the examples for CRUD operations.
let data1: MyData = { id: "1", key: "key 1", content: "content 1" };
let data2: MyData = { id: "2", key: "key 2", content: "content 2" };
let data3: MyData = { id: "3", key: "key 3", content: "content 3" };
var data1 = new MyData { Id = "1", Key = "key 1", Content="content 1" };
var data2 = new MyData { Id = "2", Key = "key 2", Content="content 2" };
var data3 = new MyData { Id = "3", Key = "key 3", Content="content 3" };
data1 := MyData{Id: "1", Key: "key 1", Content: "content 1"}
data2 := MyData{Id: "2", Key: "key 2", Content: "content 2"}
data3 := MyData{Id: "3", Key: "key 3", Content: "content 3"}
var data1 = MyData.from('1', 'key 1', 'content 1');
var data2 = MyData.from('2', 'key 2', 'content 2');
var data3 = MyData.from('3', 'key 3', 'content 3');
data1 = MyData('1', 'key 1', 'content 1')
data2 = MyData('2', 'key 2', 'content 2')
data3 = MyData('3', 'key 3', 'content 3')
MongoDbPersistence
This component can be used with any type of data object. However, all documents stored in MongoDB are identifiable, that is, they have a unique id value. This means that even if we don’t assign a unique identifier to our object, MongoDB will assign one automatically. That is the reason behind having an id field in our data structure.
Pre-requisites
To use the MongoDbPersistence component we need to insert it first. This can be done with the following command:
import { MongoDbPersistence } from 'pip-services3-mongodb-nodex';
using PipServices3.MongoDb.Persistence;
import (
mpersist "github.com/pip-services3-gox/pip-services3-mongodb-gox/persistence"
)
import 'package:pip_services3_mongodb/pip_services3_mongodb.dart';
from pip_services3_mongodb.persistence import MongoDbPersistence
Component creation
To create our MongoDB persistence component, we create a class that extends the MongoDbPersistence class. We also define an instance of this class and configure it using the configure method available from its parent class. As this method requires an input of type ConfigParams, we import this component and define the host, port, and database. Finally, we open the persistence component. Our code will look something like this:
export class MyMongoDbPersistence extends MongoDbPersistence<MyData> {
public constructor() {
super('mydata');
}
}
let persistence = new MyMongoDbPersistence();
let config = ConfigParams.fromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase"
);
persistence.configure(config);
await persistence.open(null);
public class MyMongoDbPersistence : MongoDbPersistence<MyData>
{
public MyMongoDbPersistence(): base("mydata") { }
}
var persistence = new MyMongoDbPersistence();
var config = ConfigParams.FromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase"
);
persistence.Configure(config);
await persistence.OpenAsync("123");
import (
"reflect"
conf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
mpersist "github.com/pip-services3-gox/pip-services3-mongodb-gox/persistence"
)
type MyMongoDbPersistence struct {
*mpersist.MongoDbPersistence[MyData]
}
func NewMyMongoDbPersistence() *MyMongoDbPersistence {
c := &MyMongoDbPersistence{}
c.MongoDbPersistence = mpersist.InheritMongoDbPersistence(c, "mydata")
return c
}
persistence := NewMyMongoDbPersistence()
config := conf.NewConfigParamsFromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase",
)
persistence.Configure(context.Backgroudn(), config)
err := persistence.Open(context.Backgroudn(), "")
class MyMongoDbPersistence extends MongoDbPersistence<MyData> {
MyMongoDbPersistence() : super('mydata');
}
var persistence = MyMongoDbPersiste
var config = ConfigParams.fromTuple
'connection.host', 'localhost',
'connection.port', 27017,
'connection.database', 'pipdatabase'
]);
persistence.configure(config);
await persistence.open('123');
class MyMongoDbPersistence(MongoDbPersistence):
def __init__(self):
super(MyMongoDbPersistence, self).__init__("mydata")
persistence = MyMongoDbPersistence()
from pip_services3_commons.config import ConfigParams
config = ConfigParams.from_tuples(
'connection.host', 'localhost',
'connection.port', 27017,
'connection.database', 'pipdatabase'
)
persistence.configure(config)
persistence.open("123")
Later on, once all operations have been completed, we can close our persistence component with the close() method.
await persistence.open(null);
await persistence.OpenAsync("123");
err := persistence.Open(context.Background(), "")
await persistence.open('123');
persistence.close(None)
CRUD operations
Our class inherits several methods from its parent class that can be used to perform CRUD operations. This section explores them.
Create
To store a document, we use the create method. This method asks for the correlationId and the data object. In the following example, we create a document based on the previously defined data1 object.
let result = await persistence.create(null, data1);
var result = await persistence.CreateAsync(null, data1);
item, err := persistence.Create(context.Background(), "", data1)
var res = await persistence.create(null, data1);
result = persistence.create(None, data1)
Which returns:
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.Id; // Returns '1'
result.Key; // Returns 'key 1'
result.Content; // Returns 'content 1'
result.Id // Returns '1'
result.Key // Returns 'key 1'
result.Content // Returns 'content 1'
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.id # Returns '1'
result.key # Returns 'key 1'
result.content # Returns 'content 1'
Read
The MongoDbPersistence class offers several options to extract documents from a database.
getOneRandom()
As its name suggests, this method retrieves a random document based on a given filter. In the following example, we ask to retrieve a component with a key value of ‘key 3’.
import { FilterParams } from 'pip-services3-commons-nodex';
let item = await persistence.getOneRandom(null, FilterParams.fromTuples("key", "key 3"));
using PipServices3.Commons.Data;
var item = await persistence.GetOneRandomAsync(null, FilterParams.FromTuples("key", "key 3"));
import (
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
)
item, err = persistence.GetOneRandom(context.Background(), "", cdata.NewFilterParamsFromTuples("key", "key 3"))
import 'package:pip_services3_commons/pip_services3_commons.dart';
var item = await persistence.getOneRandom(null, FilterParams.fromTuples(['key', 'key 3']));
from pip_services3_commons.data import FilterParams
result = persistence.get_one_random(None, FilterParams.from_tuples('key', 'key 3'))
Which returns:
result.id; // Returns '3'
result.key; // Returns 'key 3'
result.content; // Returns 'content 3'
result.Id; // Returns '3'
result.Key; // Returns 'key 3'
result.Content; // Returns 'content 3'
result.Id // Returns '3'
result.Key // Returns 'key 3'
result.Content // Returns 'content 3'
result.id; // Returns '3'
result.key; // Returns 'key 3'
result.content; // Returns 'content 3'
result.id # Returns '3'
result.key # Returns 'key 3'
result.content # Returns 'content 3'
getListByFilter()
This method gets a list of data items retrieved according to a given filter. In order to use it, we override this method. This action allows us to introduce any specific aspects that we may need. Our function will look something like this:
public getListByFilter(correlationId: string, filter: FilterParams, sort: SortParams): Promise<MyData[]> {
return super.getListByFilter(correlationId, this.composeFilter(filter), this.composeSort(sort), null);
}
public Task<List<MyData>> GetListByFilterAsync(string correlationId, FilterParams filterParams, SortParams sortParams = null)
{
return base.GetListByFilterAsync(correlationId, ComposeFilter(filterParams), ComposeSort(sortParams));
}
func (c *MyMongoDbPersistence) GetListByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams, sort *cdata.SortParams) (items []MyData, err error) {
return c.MongoDbPersistence.GetListByFilter(ctx, correlationId, c.composeFilter(filter), c.composeSort(sort), nil)
}
Future<List<MyData>> getListByFilter(
String? correlationId, FilterParams? filter, SortParams? sort) {
return super.getListByFilterEx(
correlationId, composeFilter(filter), composeSort(sort));
}
def get_list_by_filter(self, correlation_id: Optional[str], filter: FilterParams, sort: SortParams) -> List[MyData]:
return super().get_list_by_filter(correlation_id, self._compose_filter(filter), None, self._compose_sort(sort))
Once we have our class defined, we can call it to get our search results. For example, to get all the elements with a key value of ‘key 3’ we can write:
let list = await persistence.getListByFilter("123", FilterParams.fromTuples("key", "key 3"), null);
var list = await persistence.GetListByFilterAsync("123", FilterParams.FromTuples("key", "key 3"), null);
list, err := persistence.GetListByFilter(context.Background(), "", cdata.NewFilterParamsFromTuples("key", "key 3"), nil)
var list = await persistence.getListByFilter('123', FilterParams.fromTuples(['key', 'key 3']), null);
result = persistence.get_list_by_filter('123', FilterParams.from_tuples('key', 'key 3'), None)
Which returns:
result[0].id; // Returns '3'
result[0].key; // Returns 'key 3'
result[0].content; // Returns 'content 3'
result[0].Id; // Returns '3'
result[0].Key; // Returns 'key 3'
result[0].Content; // Returns 'content 3'
result[0].Id // Returns '3'
result[0].Key // Returns 'key 3'
result[0].Content // Returns 'content 3'
result[0].id; // Returns '3'
result[0].key; // Returns 'key 3'
result[0].content; // Returns 'content 3'
result[0].id # Returns '3'
result[0].key # Returns 'key 3'
result[0].content # Returns 'content 3'
getPageByFilter()
This method gets a page of data items retrieved according to a given filter. It also allows adding a sorting parameter and a projection object. Similar to what we did in the previous example, we override this method in our persistence class. Besides, we add two methods, namely composeFilter and composeSort. These two methods are used to define aspects that are specific to the database we are using (In our case MongoDB). An example of both methods is:
private composeFilter(filter: FilterParams): any {
filter = filter || new FilterParams();
let criteria = [];
let key = filter.getAsNullableString('key');
if (key != null)
criteria.push({ key: key });
return criteria.length > 0 ? { $and: criteria } : null;
}
private composeSort(sort: SortParams): any {
sort = sort || new SortParams();
let sortCondition = {};
for (let field of sort) {
sortCondition[field.name] = field.ascending ? 1 : 0;
}
return sortCondition;
}
protected FilterDefinition<MyData> ComposeFilter(FilterParams filterParams)
{
filterParams = filterParams ?? new FilterParams();
var builder = Builders<MyData>.Filter;
var filter = builder.Empty;
var key = filterParams.GetAsNullableString("key");
if (key != null)
filter &= builder.Eq("key", key);
return filter;
}
protected SortDefinition<MyData> ComposeSort(SortParams sortParams)
{
sortParams = sortParams ?? new SortParams();
var builder = Builders<MyData>.Sort;
var sortDefinitions = new List<SortDefinition<MyData>>();
foreach (var field in sortParams)
{
if (field.Ascending)
sortDefinitions.Add(builder.Ascending(field.Name));
else
sortDefinitions.Add(builder.Descending(field.Name));
}
var sort = builder.Combine(sortDefinitions);
return sort;
}
func (c *MyMongoDbPersistence) composeFilter(filter *cdata.FilterParams) bson.M {
if &filter == nil || filter == nil {
filter = cdata.NewEmptyFilterParams()
}
key := filter.GetAsNullableString("key")
var filterObj bson.M
if *key != "" {
filterObj = bson.M{"key": *key}
} else {
filterObj = bson.M{}
}
return filterObj
}
func (c *MyMongoDbPersistence) composeSort(sort *cdata.SortParams) bson.M {
if &sort == nil || sort == nil {
sort = cdata.NewEmptySortParams()
}
sortObj := bson.M{}
for _, field := range *sort {
if field.Ascending {
sortObj[field.Name] = 1
} else {
sortObj[field.Name] = -1
}
}
return sortObj
}
Map<String, dynamic> composeFilter(FilterParams? filter) {
filter = filter ?? FilterParams();
var key = filter.getAsNullableString('key');
var filterCondition = <String, dynamic>{};
if (key != null) {
filterCondition['key'] = key;
}
return filterCondition;
}
Map<String, dynamic> composeSort(SortParams? sort) {
sort = sort ?? SortParams(null);
var sortCondition = <String, dynamic>{};
for (var field in sort) {
sortCondition[field.name!] = field.ascending ? 1 : -1;
}
return sortCondition;
}
def _compose_filter(self, filter: FilterParams):
filter = filter or FilterParams()
key = filter.get_as_nullable_string('key')
filter_condition = {}
if key is not None:
filter_condition['key'] = key
return filter_condition
def _compose_sort(self, sort: SortParams):
sort = sort or SortParams()
compose_sort = ''
for i, filed in enumerate(sort):
compose_sort += filed.name + (' ASC' if filed.ascending else ' DESC')
return compose_sort
And, an example of get_page_by_filter() is:
public getPageByFilter(correlationId: string, filter: FilterParams, paging: PagingParams, sort: SortParams): Promise<DataPage<MyData>> {
return super.getPageByFilter(correlationId, this.composeFilter(filter), paging, this.composeSort(sort), null);
}
public Task<DataPage<MyData>> GetPageByFilterAsync(string correlationId, FilterParams filterParams, PagingParams paging = null, SortParams sortParams = null)
{
return base.GetPageByFilterAsync(correlationId, ComposeFilter(filterParams), paging, ComposeSort(sortParams));
}
func (c *MyMongoDbPersistence) GetPageByFilter(ctx context,Context, correlationId string, filter *cdata.FilterParams, paging *cdata.PagingParams, sort *cdata.SortParams) (page *DataPage[MyData], err error) {
return c.MongoDbPersistence.GetPageByFilter(ctx, correlationId,
c.composeFilter(filter), paging,
c.composeSort(sort), nil)
}
Future<DataPage<MyData>> getPageByFilter(String? correlationId,
FilterParams? filter, PagingParams? paging, SortParams? sort) async {
return super.getPageByFilterEx(
correlationId, composeFilter(filter), paging, composeSort(sort));
}
def get_page_by_filter(self, correlation_id: Optional[str], filter: FilterParams, paging: PagingParams,
sort: SortParams) -> DataPage:
return super().get_page_by_filter(correlation_id, self._compose_filter(filter), paging, self._compose_sort(sort), None)
Now, we can call this method from our persistence object. For example, to obtain all the records with a key value of ‘key 3’, we can write:
let page = await persistence.getPageByFilter(null, FilterParams.fromTuples("key", "key 3"), null, null);
var res = await persistence.GetPageByFilterAsync(null, FilterParams.FromTuples("key", "key 3"), null, null);
page, err := persistence.GetPageByFilter(context.Background(), "", cdata.NewFilterParamsFromTuples("key", "key 3"), nil, nil)
var page = await persistence.getPageByFilter('123', FilterParams.fromTuples(['key', 'key 3']), null, null);
result = persistence.get_page_by_filter(None, FilterParams.from_tuples("key", "key 3"), None, None)
which returns the searched values in a DataPage object:
result.data[0].id; // Returns '3'
result.data[0].key; // Returns 'key 3'
result.data[0].content; // Returns 'content 3'
result.Data[0].Id; // Returns '3'
result.Data[0].Key; // Returns 'key 3'
result.Data[0].Content; // Returns 'content 3'
result.Data[0].Id // Returns '3'
result.Data[0].Key // Returns 'key 3'
result.Data[0].Content // Returns 'content 3'
result.data[0].id; // Returns '3'
result.data[0].key; // Returns 'key 3'
result.data[0].content; // Returns 'content 3'
result.data[0].id # Returns '3'
result.data[0].key # Returns 'key 3'
result.data[0].content # Returns 'content 3'
getCountByFilter()
This method gets the number of data items that will be retrieved based on a given filter. Because it is a private method in other languages – such as Node.js - we need to override it. Our added method will look similar to
public getCountByFilter(correlationId: string, filter: FilterParams): Promise<number> {
return super.getCountByFilter(correlationId, this.composeFilter(filter));
}
public Task<long> GetCountByFilterAsync(string correlationId, FilterParams filterParams)
{
return base.GetCountByFilterAsync(correlationId, ComposeSort(sortParams));
}
func (c *MyMongoDbPersistence) GetCountByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams) (count int64, err error) {
return c.MongoDbPersistence.GetCountByFilter(ctx, correlationId, c.composeFilter(filter))
}
Future<int> getCountByFilter(
String? correlationId, FilterParams? filter) async {
return super.getCountByFilterEx(correlationId, composeFilter(filter));
}
def get_count_by_filter(self, correlation_id: Optional[str], filter: FilterParams) -> int:
return super().get_count_by_filter(correlation_id, self._compose_filter(filter))
Now, we can call it from our code and get the returned amount of records that comply with a given condition, such as key equal to ‘key 3’.
let count = await persistence.getCountByFilter(null, FilterParams.fromTuples("key", "key 3"));
var count = await persistence.GetCountByFilterAsync(null, FilterParams.FromTuples("key", "key 3"), null); // Returns 1
count, err := persistence.GetCountByFilter(context.Background(), "", cdata.NewFilterParamsFromTuples("key", "key 3")) // Returns 1
var count = await persistence.getCountByFilter('123', FilterParams.fromTuples(['key', 'key 3']));
result = persistence.get_count_by_filter(None, FilterParams.from_tuples('key', 'key 3')) # Returns 1
Update
As MongoDbPersistence doesn’t have an update method, we need to define it in our class. We will see how to do this in the Example section.
Delete
The MongoDbPersistence class provides the deleteByFilter() method, which deletes all those documents that comply with a given condition. The following example shows how to delete all the elements with a key value equal to ‘key 3’:
await persistence.deleteByFilter(null, FilterParams.fromTuples("key", "key 3"));
await persistence.DeleteByFilterAsync(null, FilterParams.FromTuples("key", "key 3"));
err = persistence.DeleteByFilter(context.Background(), "", cdata.NewFilterParamsFromTuples("key", "key 3"))
await persistence.deleteByFilter(null, FilterParams.fromTuples(['key', 'key 3']));
persistence.delete_by_filter(None, FilterParams.from_tuples('key', 'key 3'))
Component’s final version
After overriding and adding the methods specified in the previous examples, our MongoDb persistence component looks like this:
export class MyMongoDbPersistence extends MongoDbPersistence<MyData> {
public constructor() {
super('mydata');
}
private composeFilter(filter: FilterParams): any {
filter = filter || new FilterParams();
let criteria = [];
let key = filter.getAsNullableString('key');
if (key != null)
criteria.push({ key: key });
return criteria.length > 0 ? { $and: criteria } : null;
}
private composeSort(sort: SortParams): any {
sort = sort || new SortParams();
let sortCondition = {};
for (let field of sort) {
sortCondition[field.name] = field.ascending ? 1 : 0;
}
return sortCondition;
}
public getOneRandom(correlationId: string, filter: FilterParams): Promise<MyData> {
return super.getOneRandom(correlationId, this.composeFilter(filter));
}
public getListByFilter(correlationId: string, filter: FilterParams, sort: SortParams): Promise<MyData[]> {
return super.getListByFilter(correlationId, this.composeFilter(filter), this.composeSort(sort), null);
}
public getPageByFilter(correlationId: string, filter: FilterParams, paging: PagingParams, sort: SortParams): Promise<DataPage<MyData>> {
return super.getPageByFilter(correlationId, this.composeFilter(filter), paging, this.composeSort(sort), null);
}
public getCountByFilter(correlationId: string, filter: FilterParams): Promise<number> {
return super.getCountByFilter(correlationId, this.composeFilter(filter));
}
public deleteByFilter(correlationId: string, filter: FilterParams): Promise<void> {
return super.deleteByFilter(correlationId, this.composeFilter(filter));
}
}
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
public class MyMongoDbPersistence : MongoDbPersistence<MyData>
{
public MyMongoDbPersistence(): base("mydata") { }
protected FilterDefinition<MyData> ComposeFilter(FilterParams filterParams)
{
filterParams = filterParams ?? new FilterParams();
var builder = Builders<MyData>.Filter;
var filter = builder.Empty;
var key = filterParams.GetAsNullableString("key");
if (key != null)
filter &= builder.Eq("key", key);
return filter;
}
protected SortDefinition<MyData> ComposeSort(SortParams sortParams)
{
sortParams = sortParams ?? new SortParams();
var builder = Builders<MyData>.Sort;
var sortDefinitions = new List<SortDefinition<MyData>>();
foreach (var field in sortParams)
{
if (field.Ascending)
sortDefinitions.Add(builder.Ascending(field.Name));
else
sortDefinitions.Add(builder.Descending(field.Name));
}
var sort = builder.Combine(sortDefinitions);
return sort;
}
public Task<MyData> GetOneRandomAsync(string correlationId, FilterParams filterParams)
{
return base.GetOneRandomAsync(correlationId, ComposeFilter(filterParams));
}
public Task<List<MyData>> GetListByFilterAsync(string correlationId, FilterParams filterParams, SortParams sortParams = null)
{
return base.GetListByFilterAsync(correlationId, ComposeFilter(filterParams), ComposeSort(sortParams));
}
public Task<DataPage<MyData>> GetPageByFilterAsync(string correlationId, FilterParams filterParams, PagingParams paging = null, SortParams sortParams = null)
{
return base.GetPageByFilterAsync(correlationId, ComposeFilter(filterParams), paging, ComposeSort(sortParams));
}
public Task<long> GetCountByFilterAsync(string correlationId, FilterParams filterParams)
{
return base.GetCountByFilterAsync(correlationId, ComposeSort(sortParams));
}
public Task DeleteByFilterAsync(string correlationId, FilterParams filterParams)
{
return base.DeleteByFilterAsync(correlationId, ComposeFilter(filterParams));
}
}
import (
"reflect"
conf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
mpersist "github.com/pip-services3-gox/pip-services3-mongodb-gox/persistence"
"go.mongodb.org/mongo-driver/bson"
)
type MyMongoDbPersistence struct {
*mpersist.MongoDbPersistence
}
func NewMyMongoDbPersistence() *MyMongoDbPersistence {
c := &MyMongoDbPersistence{}
c.MongoDbPersistence = mpersist.InheritMongoDbPersistence(c, "mydata")
return c
}
func (c *MyMongoDbPersistence) composeFilter(filter *cdata.FilterParams) bson.M {
if &filter == nil || filter == nil {
filter = cdata.NewEmptyFilterParams()
}
key := filter.GetAsNullableString("key")
var filterObj bson.M
if *key != "" {
filterObj = bson.M{"key": *key}
} else {
filterObj = bson.M{}
}
return filterObj
}
func (c *MyMongoDbPersistence) composeSort(sort *cdata.SortParams) bson.M {
if &sort == nil || sort == nil {
sort = cdata.NewEmptySortParams()
}
sortObj := bson.M{}
for _, field := range *sort {
if field.Ascending {
sortObj[field.Name] = 1
} else {
sortObj[field.Name] = -1
}
}
return sortObj
}
func (c *MyMongoDbPersistence) GetListByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams, sort *cdata.SortParams) (items []MyData, err error) {
return c.MongoDbPersistence.GetListByFilter(correlationId, c.composeFilter(filter), c.composeSort(sort), nil)
}
func (c *MyMongoDbPersistence) GetPageByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams, paging *cdata.PagingParams, sort *cdata.SortParams) (page *cdata.DataPage[MyData], err error) {
return c.MongoDbPersistence.GetPageByFilter(ctx, correlationId,
c.composeFilter(filter), paging,
c.composeSort(sort), nil)
}
func (c *MyMongoDbPersistence) GetCountByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams) (count int64, err error) {
return c.MongoDbPersistence.GetCountByFilter(ctx, correlationId, c.composeFilter(filter))
}
func (c *MyMongoDbPersistence) DeleteByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams) error {
return c.MongoDbPersistence.DeleteByFilter(ctx, correlationId, c.composeFilter(filter))
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_mongodb/pip_services3_mongodb.dart';
class MyMongoDbPersistence extends MongoDbPersistence<MyData> {
MyMongoDbPersistence() : super('mydata');
Map<String, dynamic> composeFilter(FilterParams? filter) {
filter = filter ?? FilterParams();
var key = filter.getAsNullableString('key');
var filterCondition = <String, dynamic>{};
if (key != null) {
filterCondition['key'] = key;
}
return filterCondition;
}
Map<String, dynamic> composeSort(SortParams? sort) {
sort = sort ?? SortParams(null);
var sortCondition = <String, dynamic>{};
for (var field in sort) {
sortCondition[field.name!] = field.ascending ? 1 : -1;
}
return sortCondition;
}
Future<MyData?> getOneRandom(String? correlationId, FilterParams? filter) {
return super.getOneRandomEx(correlationId, composeFilter(filter));
}
Future<List<MyData>> getListByFilter(
String? correlationId, FilterParams? filter, SortParams? sort) {
return super.getListByFilterEx(
correlationId, composeFilter(filter), composeSort(sort));
}
Future<DataPage<MyData>> getPageByFilter(String? correlationId,
FilterParams? filter, PagingParams? paging, SortParams? sort) async {
return super.getPageByFilterEx(
correlationId, composeFilter(filter), paging, composeSort(sort));
}
Future<int> getCountByFilter(
String? correlationId, FilterParams? filter) async {
return super.getCountByFilterEx(correlationId, composeFilter(filter));
}
Future deleteByFilter(String? correlationId, FilterParams? filter) {
return super.deleteByFilterEx(correlationId, composeFilter(filter));
}
}
class MyMongoDbPersistence(MongoDbPersistence):
def __init__(self):
super(MyMongoDbPersistence, self).__init__("mydata2")
def _compose_filter(self, filter: FilterParams):
filter = filter or FilterParams()
key = filter.get_as_nullable_string('key')
filter_condition = {}
if key is not None:
filter_condition['key'] = key
return filter_condition
def _compose_sort(self, sort: SortParams):
sort = sort or SortParams()
compose_sort = ''
for i, filed in enumerate(sort):
compose_sort += filed.name + (' ASC' if filed.ascending else ' DESC')
return compose_sort
def get_one_random(self, correlation_id: Optional[str], filter: FilterParams) -> MyData:
return super().get_one_random(correlation_id, self._compose_filter(filter))
def get_list_by_filter(self, correlation_id: Optional[str], filter: FilterParams, sort: SortParams) -> List[MyData]:
return super().get_list_by_filter(correlation_id, self._compose_filter(filter), None, self._compose_sort(sort))
def get_page_by_filter(self, correlation_id: Optional[str], filter: FilterParams, paging: PagingParams,
sort: SortParams) -> DataPage:
return super().get_page_by_filter(correlation_id, self._compose_filter(filter), paging, self._compose_sort(sort), None)
def get_count_by_filter(self, correlation_id: Optional[str], filter: FilterParams) -> int:
return super().get_count_by_filter(correlation_id, self._compose_filter(filter))
def delete_by_filter(self, correlation_id: Optional[str], filter: FilterParams):
super().delete_by_filter(correlation_id, self._compose_filter(filter))
Example
Now, we will see a simple example that puts most of the learned concepts together. It starts by importing the necessary libraries and creating a MongoDB persistence class that includes an update method. Then, it performs CRUD operations and prints the results. The code is:
import { ConfigParams, DataPage, FilterParams, IStringIdentifiable, SortParams } from 'pip-services3-commons-nodex';
import { MongoDbPersistence } from 'pip-services3-mongodb-nodex';
export class MyData implements IStringIdentifiable {
public id: string;
public key: string;
public content: string;
}
export class MyMongoDbPersistence extends MongoDbPersistence<MyData> {
public constructor() {
super('mydata');
}
private composeFilter(filter: FilterParams): any {
filter = filter || new FilterParams();
let criteria = [];
let key = filter.getAsNullableString('key');
if (key != null)
criteria.push({ key: key });
return criteria.length > 0 ? { $and: criteria } : null;
}
public getListByFilter(correlationId: string, filter: FilterParams, sort: SortParams): Promise<MyData[]> {
return super.getListByFilter(correlationId, this.composeFilter(filter), null, null);
}
public async update(correlationId: string, item: MyData): Promise<MyData> {
if (item == null || item.id == null) {
return null;
}
let newItem = Object.assign({}, item);
delete newItem.id;
newItem = this.convertFromPublic(newItem);
let filter = { _id: item.id };
let update = { $set: newItem };
let options = {
returnDocument: "after"
};
let result = await new Promise<any>((resolve, reject) => {
this._collection.findOneAndUpdate(filter, update, options, (err, result) => {
if (err == null) resolve(result);
else reject(err);
});
});
newItem = result ? this.convertToPublic(result.value) : null;
return newItem;
}
public deleteByFilter(correlationId: string, filter: FilterParams): Promise<void> {
return super.deleteByFilter(correlationId, this.composeFilter(filter));
}
}
export function printResult(operationName: string, res: MyData) {
console.log(`==================== ${operationName} ====================`);
console.log(`MyData with id: ${res.id}`);
console.log(`MyData key: ${res.key}`);
console.log(`MyData content: ${res.content}`);
}
let data1: MyData = { id: "1", key: "key 1", content: "content 1" };
let persistence = new MyMongoDbPersistence();
let config = ConfigParams.fromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase"
);
persistence.configure(config);
await persistence.open(null);
await persistence.clear(null);
// 1 - Create
let result = await persistence.create(null, data1);
printResult("Create", result);
// 2 - Retrieve
let items = await persistence.getListByFilter("123", FilterParams.fromTuples("key", "key 1"), null);
printResult("Get by id", items[0]);
// 3 - Update
items[0].content = "new content 2";
items[0].key = "key 2";
let update = await persistence.update(null, items[0]);
printResult("Update", update);
// 4 - Delete
await persistence.deleteByFilter(null, FilterParams.fromTuples("key", "key 1"));
await persistence.close(null);
using System;
using System.Runtime.Serialization;
using PipServices3.Commons.Data;
using PipServices3.Commons.Config;
using PipServices3.MongoDb.Persistence;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Threading.Tasks;
[DataContract]
[BsonNoId]
[BsonIgnoreExtraElements]
public class MyData : IStringIdentifiable
{
[BsonElement("id")]
[DataMember(Name = "id")]
public string Id { get; set; }
[BsonElement("key")]
[DataMember(Name = "key")]
public string Key { get; set; }
[BsonElement("content")]
[DataMember(Name = "content")]
public string Content { get; set; }
}
public class MyMongoDbPersistence : MongoDbPersistence<MyData>
{
public MyMongoDbPersistence(): base("mydata") { }
protected FilterDefinition<MyData> ComposeFilter(FilterParams filterParams)
{
filterParams = filterParams ?? new FilterParams();
var builder = Builders<MyData>.Filter;
var filter = builder.Empty;
var key = filterParams.GetAsNullableString("key");
if (key != null)
filter &= builder.Eq("key", key);
return filter;
}
public Task<List<MyData>> GetListByFilterAsync(string correlationId, FilterParams filterParams, SortParams sortParams = null)
{
return base.GetListByFilterAsync(correlationId, ComposeFilter(filterParams), ComposeSort(sortParams));
}
public virtual async Task<MyData> UpdateAsync(string correlationId, MyData item)
{
if (item == null)
return null;
var filter = Builders<MyData>.Filter.Eq("id", item.Id);
var options = new FindOneAndReplaceOptions<MyData>
{
ReturnDocument = ReturnDocument.After,
IsUpsert = false
};
var result = await _collection.FindOneAndReplaceAsync(filter, item, options);
_logger.Trace(correlationId, "Update in {0} with id = {1}", _collectionName, item.Id);
return result;
}
public Task DeleteByFilterAsync(string correlationId, FilterParams filterParams)
{
return base.DeleteByFilterAsync(correlationId, ComposeFilter(filterParams));
}
}
public static void PrintResult(string operationNme, MyData res)
{
Console.WriteLine($"==================== {operationNme} ====================");
Console.WriteLine($"MyData with Id: {res.Id}");
Console.WriteLine($"MyData Key: {res.Key}");
Console.WriteLine($"MyData Content: {res.Content}");
}
var data1 = new MyData { Id = "1", Key = "key 1", Content="content 1" };
persistence = new MyMongoDbPersistence();
var config = ConfigParams.FromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "mydb"
);
persistence.Configure(config);
await persistence.OpenAsync("123");
await persistence.ClearAsync("123");
// 1 - Create
var result = await persistence.CreateAsync(null, data1);
PrintResult("Create", result);
// 2 - Retrieve
var items = await persistence.GetListByFilterAsync("123", FilterParams.FromTuples("key", "key 1"), null);
PrintResult("Get by id", items[0]);
// 3 - Update
items[0].Content = "new content 2";
items[0].Key = "key 2";
var update = await persistence.UpdateAsync(null, items[0]);
PrintResult("Update", update);
// 4 - Delete
await persistence.DeleteByFilterAsync(null, FilterParams.FromTuples("key", "key 1"));
await persistence.CloseAsync("123");
import (
"fmt"
"reflect"
conf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
datpersist "github.com/pip-services3-gox/pip-services3-data-gox/persistence"
mpersist "github.com/pip-services3-gox/pip-services3-mongodb-gox/persistence"
mngoptions "go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
type MyMongoDbPersistence struct {
*mpersist.MongoDbPersistence[MyData]
}
func NewMyMongoDbPersistence() *MyMongoDbPersistence {
c := &MyMongoDbPersistence{}
c.MongoDbPersistence = mpersist.InheritMongoDbPersistence(c, "mydata")
return c
}
func (c *MyMongoDbPersistence) composeFilter(filter *cdata.FilterParams) bson.M {
if &filter == nil || filter == nil {
filter = cdata.NewEmptyFilterParams()
}
key := filter.GetAsNullableString("key")
var filterObj bson.M
if *key != "" {
filterObj = bson.M{"key": *key}
} else {
filterObj = bson.M{}
}
return filterObj
}
func (c *MyMongoDbPersistence) Update(ctx context.Context, correlationId string, item MyData) (result MyData, err error) {
newItem := c.ConvertFromPublic(item)
id := newItem["_id"]
filter := bson.M{"_id": id}
update := bson.D{{"$set", newItem}}
var options mngoptions.FindOneAndUpdateOptions
retDoc := mngoptions.After
options.ReturnDocument = &retDoc
fuRes := c.Collection.FindOneAndUpdate(ctx, filter, update, &options)
if fuRes.Err() != nil {
return result, fuRes.Err()
}
c.Logger.Trace(correlationId, "Updated in %s with id = %s", c.CollectionName, id)
var docPointer T
err = fuRes.Decode(&docPointer)
if err != nil {
if err == mongo.ErrNoDocuments {
return result, nil
}
return result, err
}
result = c.Overrides.ConvertToPublic(docPointer)
return result, nil
}
func (c *MyMongoDbPersistence) GetListByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams, sort *cdata.SortParams) (items []MyData, err error) {
return c.MongoDbPersistence.GetListByFilter(ctx, correlationId, c.composeFilter(filter), c.composeSort(sort), nil)
}
func (c *MyMongoDbPersistence) DeleteByFilter(ctx context.Context, correlationId string, filter *cdata.FilterParams) error {
return c.MongoDbPersistence.DeleteByFilter(ctx, correlationId, c.composeFilter(filter))
}
type MyData struct {
Id string `bson:"_id" json:"id"`
Key string `bson:"key" json:"key"`
Content string `bson:"content" json:"content"`
}
type MyDataPage struct {
Total *int64 `bson:"total" json:"total"`
Data []MyData `bson:"data" json:"data"`
}
func PrintResult(operationName string, res MyData) {
fmt.Println("==================== " + operationName + " ====================")
fmt.Println("MyData with Id: " + res.Id)
fmt.Println("MyData with Key: " + res.Key)
fmt.Println("MyData with Content: " + res.Content)
}
func main() {
data1 := MyData{Id: "1", Key: "key 1", Content: "content 1"}
persistence := NewMyMongoDbPersistence()
config := conf.NewConfigParamsFromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase",
)
persistence.Configure(context.Background(), config)
_ = persistence.Open(context.Background(), "")
_ = persistence.Clear(context.Background(), "")
// 1 - Create
result, _ := persistence.Create(context.Background(), "123", data1)
PrintResult("Create", result)
// 2 - Retrieve
items, _ := persistence.GetListByFilter(context.Background(), "123", cdata.NewFilterParamsFromTuples("key", "key 1"), nil)
PrintResult("Get by id", items[0])
// 3 - Update
items[0].Content = "new content 2"
items[0].Key = "key 2"
update, _ := persistence.Update(context.Background(), "123", items[0])
PrintResult("Update", update)
// 4 - Delete
_ = persistence.DeleteByFilter(context.Background(), "123", cdata.NewFilterParamsFromTuples("key", "key 1"))
_ = persistence.Close(context.Background(), "123")
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_mongodb/pip_services3_mongodb.dart';
class MyData implements IStringIdentifiable, ICloneable {
@override
String? id;
String? key;
String? content;
MyData();
MyData.from(this.id, this.key, this.content);
Map<String, dynamic> toJson() {
return <String, dynamic>{'id': id, 'key': key, 'content': content};
}
void fromJson(Map<String, dynamic> json) {
id = json['id'];
key = json['key'];
content = json['content'];
}
@override
MyData clone() {
return MyData.from(id, key, content);
}
}
class MyMongoDbPersistence extends MongoDbPersistence<MyData> {
MyMongoDbPersistence() : super('mydata');
Map<String, dynamic> composeFilter(FilterParams? filter) {
filter = filter ?? FilterParams();
var key = filter.getAsNullableString('key');
var filterCondition = <String, dynamic>{};
if (key != null) {
filterCondition['key'] = key;
}
return filterCondition;
}
Future<MyData?> update(String? correlationId, MyData? item) async {
if (item == null || item.id == null) {
return null;
}
var jsonMap = convertFromPublic(item, createUid: false);
jsonMap?.remove('_id');
var filter = {'_id': item.id};
var update = {r'$set': jsonMap};
var result = await collection?.findAndModify(
query: filter, update: update, returnNew: true, upsert: false);
return result != null ? convertToPublic(result) : null;
}
Future<List<MyData>> getListByFilter(
String? correlationId, FilterParams? filter, SortParams? sort) {
return super.getListByFilterEx(
correlationId, composeFilter(filter), composeSort(sort));
}
Future deleteByFilter(String? correlationId, FilterParams? filter) {
return super.deleteByFilterEx(correlationId, composeFilter(filter));
}
}
void printResult(String operationName, MyData res) {
print('==================== $operationName ====================');
print('MyData with id: ${res.id}');
print('MyData key: ${res.key}');
print('MyData content: ${res.content}');
}
void main(List<String> arguments) async {
var data1 = MyData.from('1', 'key 1', 'content 1');
var persistence = MyMongoDbPersistence();
var config = ConfigParams.fromTuples([
'connection.host',
'localhost',
'connection.port',
27017,
'connection.database',
'pipdatabase'
]);
persistence.configure(config);
await persistence.open(null);
await persistence.clear(null);
// 1 - Create
var result = await persistence.create(null, data1);
printResult('Create', result!);
// 2 - Retrieve
var items = await persistence.getListByFilter(
'123', FilterParams.fromTuples(['key', 'key 1']), null);
printResult('Get by id', items[0]);
// 3 - Update
items[0].content = 'new content 2';
items[0].key = 'key 2';
var update = await persistence.update(null, items[0]);
printResult('Update', update!);
// 4 - Delete
await persistence.deleteByFilter(
null, FilterParams.fromTuples(['key', 'key 1']));
await persistence.close(null);
}
from copy import deepcopy
from typing import Optional, Any
import pymongo
from pip_services3_commons.config import ConfigParams
from pip_services3_commons.data import IStringIdentifiable, FilterParams
from pip_services3_mongodb.persistence import MongoDbPersistence
class MyData(IStringIdentifiable):
def __init__(self, id: str = None, key: str = None, content: str = None):
self.id = id
self.key = key
self.content = content
class MyMongoDbPersistence(MongoDbPersistence):
def __init__(self):
super(MyMongoDbPersistence, self).__init__("mydata")
def _compose_filter(self, filter: FilterParams):
filter = filter or FilterParams()
key = filter.get_as_nullable_string('key')
filter_condition = {}
if key is not None:
filter_condition['key'] = key
return filter_condition
def get_list_by_filter(self, correlation_id: Optional[str], filter: FilterParams, sort: SortParams) -> List[MyData]:
return super().get_list_by_filter(correlation_id, self._compose_filter(filter), None, None)
def update(self, correlation_id: Optional[str], item: Any) -> Any:
if item is None or item.id is None:
return
new_item = deepcopy(item)
new_item = self._convert_from_public(new_item)
_id = item.id
result = self._collection.find_one_and_update(
{'_id': _id}, {'$set': new_item},
return_document=pymongo.ReturnDocument.AFTER
)
new_item = self._convert_to_public(result)
return new_item
def delete_by_filter(self, correlation_id: Optional[str], filter: FilterParams):
super().delete_by_filter(correlation_id, self._compose_filter(filter))
data1 = MyData(None, 'key 1', 'content 1')
persistence = MyMongoDbPersistence()
config = ConfigParams.from_tuples(
'connection.host', 'localhost',
'connection.port', 27017,
'connection.database', 'mydb'
)
persistence.configure(config)
persistence.open("123")
persistence.clear("123")
def print_result(operation_name: str, res: MyData):
print(f"==================== {operation_name} ====================")
print(f'MyData with Id: {res.id}')
print(f'MyData Key: {res.key}')
print(f'MyData Content: {res.content}')
# CRUD
# 1 - Create
result = persistence.create(None, data1)
print_result('Create', result)
# 2 - Retrieve
items = persistence.get_list_by_filter('123', FilterParams.from_tuples('key', 'key 1'), None)
print_result('Get by id', items[0])
# 3 - Update
items[0].content = 'new content 2'
items[0].key = 'key 2'
update = persistence.update(None, items[0])
print_result('Update', update)
# 4 - Delete
persistence.delete_by_filter(None, FilterParams.from_tuples('key', 'key 1'))
persistence.close("123")
And the output is:
IdentifiableMongoDbPersistence
This component is used to perform CRUD operations with identifiable data objects, that is, objects that can be identified via a unique id.
Pre-requisites
To use the IdentifiableMongoDbPersistence component we need to import it first. This can be done with the following command:
import { IdentifiableMongoDbPersistence } from 'pip-services3-mongodb-nodex';
using PipServices3.MongoDb.Persistence;
import (
mpersist "github.com/pip-services3-gox/pip-services3-mongodb-gox/persistence"
)
import 'package:pip_services3_mongodb/pip_services3_mongodb.dart';
from pip_services3_mongodb.persistence import IdentifiableMongoDbPersistence
Component creation
To create an identifiable MongoDB persistence component, we create a subclass of the IdentifiableMongoDbPersistence class where we specify the name of the table we will be using (In our example: mydata). We also define an instance of it and, via the configure() method, we add the connection parameters. In our example, we use a local database and we connect to it through the default port 27017. We also define a database named “pipdatabase”.
import { ConfigParams } from 'pip-services3-commons-nodex';
export class MyIdentifiableMongoDbPersistence extends IdentifiableMongoDbPersistence<MyData, string> {
public constructor() {
super("mydata");
}
}
let persistence = new MyIdentifiableMongoDbPersistence();
let config = ConfigParams.fromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase"
);
persistence.configure(config);
using PipServices3.Commons.Config;
public class MyIdentifiableMongoDbPersistence: IdentifiableMongoDbPersistence<MyData, string>
{
public MyIdentifiableMongoDbPersistence() : base("mydata") { }
}
var persistence = new MyMongoDbPersistence();
var config = ConfigParams.FromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase"
);
persistence.Configure(config);
import (
"fmt"
"reflect"
conf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
mpersist "github.com/pip-services3-gox/pip-services3-mongodb-gox/persistence"
)
type MyIdentifiableMongoDbPersistence struct {
*mpersist.IdentifiableMongoDbPersistence[MyData, string]
}
func NewMyIdentifiableMongoDbPersistencee() *MyIdentifiableMongoDbPersistence {
c := &MyIdentifiableMongoDbPersistence{}
c.IdentifiableMongoDbPersistence = *mpersist.InheritIdentifiableMongoDbPersistence(c, "mydata")
return c
}
persistence := NewMyIdentifiableMongoDbPersistencee()
config := conf.NewConfigParamsFromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase",
)
persistence.Configure(context.Background(), config)
import 'package:pip_services3_commons/pip_services3_commons.dart';
class MyIdentifiableMongoDbPersistence
extends IdentifiableMongoDbPersistence<MyData, String> {
MyIdentifiableMongoDbPersistence() : super('mydata');
}
var persistence = MyIdentifiableMongoDbPersistence();
var config = ConfigParams.fromTuples([
'connection.host','localhost',
'connection.port', 27017,
'connection.database', 'pipdatabase'
]);
persistence.configure(config);
class MyIdentifiableMongoDbPersistence(IdentifiableMongoDbPersistence):
def __init__(self):
super(MyIdentifiableMongoDbPersistence, self).__init__("mydata")
persistence = MyIdentifiableMongoDbPersistence()
from pip_services3_commons.config import ConfigParams
config = ConfigParams.from_tuples(
'connection.host', 'localhost',
'connection.port', 27017,
'connection.database', 'pipdatabase'
)
persistence.configure(config)
And, after creating it, we open the connection.
await persistence.open(null);
await persistence.OpenAsync(null);
_ = persistence.Open(context.Background(), "")
await persistence.open(null);
persistence.open("123")
Later on, once we have finished using this persistence component, we can close it with the close() method.
await persistence.clear(null);
await persistence.CloseAsync(null);
_ = persistence.Clear(context.Background(), "")
await persistence.clear(null);
persistence.close(None)
CRUD operations
This class presents a set of methods for CRUD operations. This section explains their usage and provides examples for each of them.
Create
This component presents two methods that allow us to create a document in MongoDB. They are:
Read
create()
To add a new document to our collection, we can use the create() method, which accepts the correlationId and the data item as inputs. The example below shows how to use it.
let result = await persistence.create(null, data1);
var result = await persistence.CreateAsync(null, data1);
result, _ := persistence.Create(context.Background(), "123", data1)
var result = await persistence.create(null, data1);
result = persistence.create(None, data1)
Which returns:
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.Id; // Returns '1'
result.Key; // Returns 'key 1'
result.Content; // Returns 'content 1'
result.Id // Returns '1'
result.Key // Returns 'key 1'
result.Content // Returns 'content 1'
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.id # Returns '1'
result.key # Returns 'key 1'
result.content # Returns 'content 1'
set()
This method updates an existing data item. If the item doesn’t exist, it creates it. The example below shows how to use it.
data1 = { id: "1", key: "key 1", content: "new content 1" };
result = await persistence.set(null, data1);
data1 = new MyData { Id = "1", Key = "key 1", Content = "new content 1" };
result = await persistence.SetAsync(null, data1);
data1 = MyData{Id: "1", Key: "key 1", Content: "new content 1"}
result, _ = persistence.Set(context.Background(), "123", data1)
data1 = MyData.from('1', 'key 1', 'new content 1');
result = await persistence.set('123', data1);
data1 = MyData('1', 'key 1', 'new content 1')
result = persistence.set(None, data1)
Which returns:
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'new content 1'
result.Id; // Returns '1'
result.Key; // Returns 'key 1'
result.Content; // Returns 'new content 1'
result.Id // Returns '1'
result.Key // Returns 'key 1'
result.Content // Returns 'new content 1'
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'new content 1'
result.id # Returns '1'
result.key # Returns 'key 1'
result.content # Returns 'new content 1'
get_one_by_id()
To retrieve a data object, we can use the get_one_by_id method, which allows for the selection of a data object based on its id. In the following example, we obtain the item with key = ‘1’.
result = await persistence.getOneById(null, "1");
result = await persistence.GetOneByIdAsync(null, "1");
result, _ = persistence.GetOneById(context.Background(), "123", "1")
result = await persistence.getOneById(null, '1');
result = persistence.get_one_by_id(None, '1')
Which returns:
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.Id; // Returns '1'
result.Key; // Returns 'key 1'
result.Content; // Returns 'content 1'
result.Id // Returns '1'
result.Key // Returns 'key 1'
result.Content // Returns 'content 1'
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.id # Returns '1'
result.key # Returns 'key 1'
result.content # Returns 'content 1'
getListByIds()
We can also use the getListByIds() method, which is similar to the previous one, but accepts a list containing ids and retrieves the documents related to those ids. In the following example, we search for those items with id equal to ‘1’ and ‘2’.
let resList = await persistence.getListByIds(null, ["1", "2"]);
var resList = await persistence.GetListByIdsAsync(null, new string[] { "1", "2"});
list, _ := persistence.GetListByIds(context.Background(), "123", []string{"1", "2"})
var resList = await persistence.getListByIds(null, ['1', '2']);
result = persistence.get_list_by_ids(None, ['1','2'])
Which returns:
result[0].id; // Returns '1'
result[0].key; // Returns 'key 1'
result[0].content; // Returns 'content 1'
result[1].id; // Returns '2'
result[1].key; // Returns 'key 2'
result[1].content; // Returns 'content 2'
result[0].Id; // Returns '1'
result[0].Key; // Returns 'key 1'
result[0].Content; // Returns 'content 1'
result[1].Id; // Returns '2'
result[1].Key; // Returns 'key 2'
result[1].Content; // Returns 'content 2'
result[0].Id // Returns '1'
result[0].Key // Returns 'key 1'
result[0].Content // Returns 'content 1'
result[1].Id // Returns '2'
result[1].Key // Returns 'key 2'
result[1].Content // Returns 'content 2'
result[0].id; // Returns '1'
result[0].key; // Returns 'key 1'
result[0].content; // Returns 'content 1'
result[1].id; // Returns '2'
result[1].key; // Returns 'key 2'
result[1].content; // Returns 'content 2'
result[0].id # Returns '1'
result[0].key # Returns 'key 1'
result[0].content # Returns 'content 1'
result[1].id # Returns '2'
result[1].key # Returns 'key 2'
result[1].content # Returns 'content 2'
Update
update()
This method updates the data stored in a record. It accepts the correlationId and the id of the record to be updated as input parameters. In the example below, we change the value of content to ‘new content 2’ for a record with id equal to ‘2’.
let updated = await persistence.update(null, { id: "2", key: "key 2", content: "new content 2" });
var updated = await persistence.UpdateAsync(null, new MyData { Id = "2", Key = "key 2", Content = "new content 2" });
updated, _ := persistence.Update(context.Background(), "123", MyData{Id: "2", Key: "key 2", Content: "new content 2"})
var updated = await persistence.update(null, MyData.from('2', 'key 2', 'new content 2'));
result = persistence.update(None, MyData('2', 'key 2', 'new content 2') )
Which returns:
result.id; // Returns '2'
result.key; // Returns 'key 2'
result.content; // Returns 'new content 2'
result.Id; // Returns '2'
result.Key; // Returns 'key 2'
result.Content; // Returns 'new content 2'
result.Id // Returns '2'
result.Key // Returns 'key 2'
result.Content // Returns 'new content 2'
result.id; // Returns '2'
result.key; // Returns 'key 2'
result.content; // Returns 'new content 2'
result.id # Returns '2'
result.key # Returns 'key 2'
result.content # Returns 'new content 2'
updatePartially()
This method also updates an item, but only the specified fields. It takes the id of the item to be updated and an AnyValueMap object containing the fields to be modified and their updated values as input parameters. The following example shows how to update the content field for a record with id equal to ‘3’.
import { AnyValueMap } from 'pip-services3-commons-nodex';
updated = await persistence.updatePartially(null, "2", AnyValueMap.fromTuples("content", "new content 2 - partially updated"));
using PipServices3.Commons.Data;
result = await persistence.UpdatePartiallyAsync(null, "2", AnyValueMap.FromTuples("content", "new content 2 - partially updated"));
import (
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
)
updated, _ = persistence.UpdatePartially(context.Background(), "123", "2", cdata.NewAnyValueMapFromTuples(
"content", "new content 2 - partially updated",
))
import 'package:pip_services3_commons/pip_services3_commons.dart';
updated = await persistence.updatePartially(null, '2',AnyValueMap.fromTuples(['content', 'new content 2 - partially updated']));
from pip_services3_commons.data import AnyValueMap
result = persistence.update_partially(None, '2', AnyValueMap({'content': 'new content 2 - partially updated'}))
Which returns:
result.id; // Returns '2'
result.key; // Returns 'key 2'
result.content; // Returns 'new content 2 - partially updated'
result.Id; // Returns '2'
result.Key; // Returns 'key 2'
result.Content; // Returns 'new content 2 - partially updated'
result.Id // Returns '2'
result.Key // Returns 'key 2'
result.Content // Returns 'new content 2 - partially updated'
result.id; // Returns '2'
result.key; // Returns 'key 2'
result.content; // Returns 'new content 2 - partially updated'
result.id # Returns '2'
result.key # Returns 'key 2'
result.content # Returns 'new content 2 - partially updated'
Delete
deleteById()
We can delete a stored data object by using the delete() method. Here, we need to indicate the correlationId and the id of the object to be deleted. The following example deletes a record with an id equal to ‘1’.
let deleted = await persistence.deleteById(null, "1");
result = await persistence.DeleteByIdAsync(null, "1");
deleted, _ := persistence.DeleteById(context.Background(), "123", "1")
var deleted = await persistence.deleteById(null, '1');
result = persistence.delete_by_id(None, '1')
Which returns:
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.Id; // Returns '1'
result.Key; // Returns 'key 1'
result.Content; // Returns 'content 1'
result.Id // Returns '1'
result.Key // Returns 'key 1'
result.Content // Returns 'content 1'
result.id; // Returns '1'
result.key; // Returns 'key 1'
result.content; // Returns 'content 1'
result.id # Returns '1'
result.key # Returns 'key 1'
result.content # Returns 'content 1'
deleteByIds
This method accepts a list containing the ids of the documents to be deleted. The following example shows how to delete the records with ids equal to ‘1’ and ‘2’.
await persistence.deleteByIds(null, ["1", "2"]);
await persistence.DeleteByIdsAsync(null, new string[] { "1", "2" });
_ = persistence.DeleteByIds(context.Background(), "123", []string{"1", "2"})
await persistence.deleteByIds(null, ['1', '2']);
persistence.delete_by_ids(None, ['1', '2'])
Example
To summarize, we put everything together in one comprehensive example. In it, we first create a data class with a field named id. Then, we create our persistence object, configure it and open the connection. Once we are connected to the database “mydb”, we perform the four CRUD operations and print the results. The code is:
import { AnyValueMap, ConfigParams, FilterParams, IStringIdentifiable, SortParams } from 'pip-services3-commons-nodex';
import { IdentifiableMongoDbPersistence } from 'pip-services3-mongodb-nodex';
export class MyIdentifiableMongoDbPersistence extends IdentifiableMongoDbPersistence<MyData, string> {
public constructor() {
super("mydata");
}
}
export class MyData implements IStringIdentifiable {
public id: string;
public key: string;
public content: string;
}
export function printResult(operationName: string, res: MyData) {
console.log(`==================== ${operationName} ====================`);
console.log(`MyData with id: ${res.id}`);
console.log(`MyData key: ${res.key}`);
console.log(`MyData content: ${res.content}`);
}
let data1: MyData = { id: "1", key: "key 1", content: "content 1" };
let persistence = new MyIdentifiableMongoDbPersistence();
let config = ConfigParams.fromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase"
);
persistence.configure(config);
await persistence.open(null);
await persistence.clear(null);
// CRUD
// 1 - Create
let result = await persistence.create(null, data1);
printResult("Create", result);
// 2 - Retrieve
let item = await persistence.getOneById("123", "1");
printResult("Get by id", item);
// 3 - Update
let update = await persistence.update(null, { id: "2", key: "key 2", content: "new content 2" });
printResult("Update", update);
// 4 - Delete
let deleted = await persistence.deleteById(null, "1");
printResult("Delete by id", deleted);
await persistence.close(null);
using System;
using System.Runtime.Serialization;
using PipServices3.Commons.Data;
using PipServices3.Commons.Config;
using PipServices3.MongoDb.Persistence;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Threading.Tasks;
public class MyIdentifiableMongoDbPersistence: IdentifiableMongoDbPersistence<MyData, string>
{
public MyIdentifiableMongoDbPersistence() : base("mydata") { }
}
[DataContract]
[BsonNoId]
[BsonIgnoreExtraElements]
public class MyData : IStringIdentifiable
{
[BsonElement("id")]
[DataMember(Name = "id")]
public string Id { get; set; }
[BsonElement("key")]
[DataMember(Name = "key")]
public string Key { get; set; }
[BsonElement("content")]
[DataMember(Name = "content")]
public string Content { get; set; }
}
public static void PrintResult(string operationNme, MyData res)
{
Console.WriteLine($"==================== {operationNme} ====================");
Console.WriteLine($"MyData Key: {res.Id}");
Console.WriteLine($"MyData Key: {res.Key}");
Console.WriteLine($"MyData Key: {res.Content}");
}
var data1 = new MyData { Id = "1", Key = "key 1", Content = "content 1" };
var config = ConfigParams.FromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase"
);
var persistence = new MyIdentifiableMongoDbPersistence();
persistence.Configure(config);
await persistence.OpenAsync("123");
await persistence.ClearAsync("123");
// CRUD
// 1 - Create
var result = await persistence.CreateAsync(null, data1);
PrintResult("Create", result);
// 2 - Retrieve
var item = await persistence.GetOneByIdAsync("123", "1");
PrintResult("Get by id", item);
// 3 - Update
var update = await persistence.UpdateAsync(null, new MyData { Id = "1", Key = "key 2", Content = "new content 2" });
PrintResult("Update", update);
// 4 - Delete
var delete = await persistence.DeleteByIdAsync(null, "1");
PrintResult("Delete by id", delete);
await persistence.CloseAsync(null);
import (
"fmt"
"reflect"
conf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
cdata "github.com/pip-services3-gox/pip-services3-commons-gox/data"
datpersist "github.com/pip-services3-gox/pip-services3-data-gox/persistence"
mpersist "github.com/pip-services3-gox/pip-services3-mongodb-gox/persistence"
mngoptions "go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
type MyIdentifiableMongoDbPersistence struct {
*mpersist.IdentifiableMongoDbPersistence[MyData, string]
}
func NewMyIdentifiableMongoDbPersistencee() *MyIdentifiableMongoDbPersistence {
c := &MyIdentifiableMongoDbPersistence{}
c.IdentifiableMongoDbPersistence = mpersist.InheritIdentifiableMongoDbPersistence(c, "mydata")
return c
}
func PrintResult(operationName string, res MyData) {
fmt.Println("==================== " + operationName + " ====================")
fmt.Println("MyData with Id: " + res.Id)
fmt.Println("MyData with Key: " + res.Key)
fmt.Println("MyData with Content: " + res.Content)
}
func main() {
data1 := MyData{Id: "1", Key: "key 1", Content: "content 1"}
persistence := NewMyIdentifiableMongoDbPersistencee()
config := conf.NewConfigParamsFromTuples(
"connection.host", "localhost",
"connection.port", 27017,
"connection.database", "pipdatabase",
)
persistence.Configure(context.Background(), config)
_ = persistence.Open(context.Background(), "123")
_ = persistence.Clear(context.Background(), "123")
// CRUD
// 1 - Create
result, _ := persistence.Create(context.Background(), "123", data1)
PrintResult("Create", result)
// 2 - Retrieve
item, _ := persistence.GetOneById(context.Background(), "123", "1")
PrintResult("Get by id", item)
// 3 - Update
update, _ := persistence.Update(context.Background(), "123", MyData{Id: "1", Key: "key 2", Content: "new content 2"})
PrintResult("Update", update)
// 4 - Delete
delete, _ := persistence.DeleteById(context.Background(), "123", "1")
PrintResult("Delete by id", delete)
_ = persistence.Close(context.Background(), "123")
}
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_mongodb/pip_services3_mongodb.dart';
class MyIdentifiableMongoDbPersistence
extends IdentifiableMongoDbPersistence<MyData, String> {
MyIdentifiableMongoDbPersistence() : super('mydata');
}
class MyData implements IStringIdentifiable, ICloneable {
@override
String? id;
String? key;
String? content;
MyData();
MyData.from(this.id, this.key, this.content);
Map<String, dynamic> toJson() {
return <String, dynamic>{'id': id, 'key': key, 'content': content};
}
void fromJson(Map<String, dynamic> json) {
id = json['id'];
key = json['key'];
content = json['content'];
}
@override
MyData clone() {
return MyData.from(id, key, content);
}
}
void printResult(String operationName, MyData res) {
print('==================== $operationName ====================');
print('MyData with id: ${res.id}');
print('MyData key: ${res.key}');
print('MyData content: ${res.content}');
}
void main(List<String> arguments) async {
var data1 = MyData.from('1', 'key 1', 'content 1');
var persistence = MyIdentifiableMongoDbPersistence();
var config = ConfigParams.fromTuples([
'connection.host', 'localhost',
'connection.port', 27017,
'connection.database', 'pipdatabase'
]);
persistence.configure(config);
await persistence.open(null);
await persistence.clear(null);
// CRUD
// 1 - Create
var result = await persistence.create(null, data1);
printResult('Create', result!);
// 2 - Retrieve
var item = await persistence.getOneById('123', '1');
printResult('Get by id', item!);
// 3 - Update
var update = await persistence.update(
null, MyData.from('1', 'key 1', 'new content 1'));
printResult('Update', update!);
// 4 - Delete
var deleted = await persistence.deleteById(null, '1');
printResult('Delete by id', deleted!);
await persistence.close(null);
await persistence.close(null);
}
from pip_services3_mongodb.persistence import IdentifiableMongoDbPersistence
from pip_services3_commons.config import ConfigParams
import pymongo
class MyIdentifiableMongoDbPersistence(IdentifiableMongoDbPersistence):
def __init__(self):
super(MyIdentifiableMongoDbPersistence, self).__init__("mydata")
persistence = MyIdentifiableMongoDbPersistence()
from pip_services3_commons.data import IStringIdentifiable
class MyData(IStringIdentifiable):
def __init__(self, id: str = None, key: str = None, content: str = None):
self.id = id
self.key = key
self.content = content
data1 = MyData('1', 'key 1', 'content 1')
config = ConfigParams.from_tuples(
'connection.host', 'localhost',
'connection.port', 27017,
'connection.database', 'mydb'
)
persistence.configure(config)
persistence.open("123")
persistence.clear("123")
def print_result(operation_name: str, res: MyData):
print(f"==================== {operation_name} ====================")
print(f'MyData with ID: {res.id}')
print(f'MyData Key: {res.key}')
print(f'MyData Content: {res.content}')
# CRUD
# 1 - Create
result = persistence.create(None, data1)
print_result('Create', result)
# 2 - Retrieve
item = persistence.get_one_by_id('123','1')
print_result('Get by id', item)
# 3 - Update
update = persistence.update(None, MyData('1', 'key 2', 'new content 2') )
print_result('Update', update)
# 4 - Delete
delete = persistence.delete_by_id(None, "1")
print_result('Delete by id', delete)
persistence.close(None)
And the output is:
Wrapping up
In this tutorial, we have explored how to create MongoDB persistence components. We saw two different components, namely the MongoDbPersistence and the IdentifiableMongoDbPersistence classes, and how to perform CRUD operations with them. Finally, we saw a comprehensive example for each component.