SlideShare a Scribd company logo
1 of 42
Download to read offline
MongoDB World 2014
by S.D.O.C. Ltd.
Billing on top of MongoDB
Ofer Cohen
Who Am I ?
● Open source evangelist
● Former Board member of OpenSourceMatters
(Non-profit organization behind Joomla)
● S.D.O.C. Ltd. Co-Founder
FUD
● FUD: Fear, Uncertainty and Doubt
● Tactic used in sales, marketing, public
relations, politics and propaganda.
Wikipedia
FUD
Preferred name for the presentation
S.D.O.C. Ltd. vision
We increase business success through great
open source technologies and services
○ Open & Transparent
○ Don't reinvent the wheel
○ High Quality
○ Lean & Effective
How did we get to billing (history)
● Client: Golan Telecom (Israel)
How did we get to billing (history)
● Client: Golan Telecom
○ New & lean player in the market
○ 0=>~1M subscribers in few years
○ Limited resources & loves open source
How did we get to billing (history)
● Client: Golan Telecom
○ Start up environment from Day 1
○ Short and aggressive time to market
○ Unlimited plan for ~25$
○ Customer can do almost everything using the website
■ Obviously requires 24/7 uptime
How did we get to billing (history)
● Start with Anti-Fraud solution
● 2 Different data structure, 2 separated tables
○ Outgoing calls (MOC)
○ incoming calls (MTC)
○ SMS (duration=0 means SMS)
Anti-Fraud in RDBMS
How did it look like? Example code...
$base_query = "SELECT imsi FROM moc WHERE callEventStartTimeStamp >=" . $start
. " UNION SELECT imsi FROM mtc WHERE callEventStartTimeStamp >=" . $start
$base_query = "SELECT imsi FROM (" . $base_query . ") AS qry ";
if (isset($args['imsi']))
$base_query .= "WHERE imsi = '" . $this->_connection->real_escape_string($args['imsi']) . "'";
$base_query .= "GROUP BY imsi ";
$mtc_join_query = "SELECT 'mtc' AS type, imsi, SUM(callEventDuration) AS duration, SUM(CEILING(callEventDuration/60)*60) AS duration_round "
. ", SUM(chargeAmount) charge "
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)='972', callEventDuration, IF(CHAR_LENGTH(callingNumber)<=10, callEventDuration, 0))) AS israel_duration
"
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)='972', CEILING(callEventDuration/60)*60, IF(CHAR_LENGTH(callingNumber)<=10, CEILING
(callEventDuration/60)*60, 0))) AS israel_duration_round "
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)!='972', IF(CHAR_LENGTH(callingNumber)>10, callEventDuration, 0), 0)) AS non_israel_duration "
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)!='972', IF(CHAR_LENGTH(callingNumber)>10, CEILING(callEventDuration/60)*60, 0), 0)) AS
non_israel_duration_round "
. ", SUM(IF(callEventDuration = 0, 1, 0)) AS sms_count "
Anti-Fraud in RDBMS
How did it look like? Example code...
. "FROM mtc "
. "WHERE callEventStartTimeStamp >=" . $start . " "
. "GROUP BY type, imsi";
$moc_join_query = "SELECT 'moc' AS type, imsi, SUM(callEventDuration) AS duration, SUM(CEILING(callEventDuration/60)*60) AS duration_round "
. ", SUM(chargeAmount) charge "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)='972', callEventDuration, IF(CHAR_LENGTH(connectedNumber)<=10, callEventDuration, 0))) AS
israel_duration "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)='972', CEILING(callEventDuration/60)*60, IF(CHAR_LENGTH(connectedNumber)<=10, CEILING
(callEventDuration/60)*60, 0))) AS israel_duration_round "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)!='972', IF(CHAR_LENGTH(connectedNumber)>10, callEventDuration, 0), 0)) AS non_israel_duration "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)!='972', IF(CHAR_LENGTH(connectedNumber)>10, CEILING(callEventDuration/60)*60, 0), 0)) AS
non_israel_duration_round "
. ", SUM(IF(callEventDuration = 0, 1, 0)) AS sms_count "
. "FROM moc "
. "WHERE callEventStartTimeStamp >=" . $start . " "
. "GROUP BY type, imsi";
Anti-Fraud in RDBMS
How did it look like? Example code...
$group_query = "SELECT base.imsi, moc.duration AS moc_duration, moc.charge AS moc_charge, "
. "mtc.duration AS mtc_duration, mtc.charge AS mtc_charge, "
. "mtc.duration_round AS mtc_duration_round, moc.duration_round AS moc_duration_round, "
. "moc.israel_duration AS moc_israel_duration, moc.non_israel_duration AS moc_non_israel_duration, "
. "moc.israel_duration_round AS moc_israel_duration_round, moc.non_israel_duration_round AS
moc_non_israel_duration_round, "
. "mtc.israel_duration AS mtc_israel_duration, mtc.non_israel_duration AS mtc_non_israel_duration, "
. "mtc.israel_duration_round AS mtc_israel_duration_round, mtc.non_israel_duration_round AS
mtc_non_israel_duration_round, "
. "mtc.sms_count AS mtc_sms_count, moc.sms_count AS moc_sms_count "
. "FROM "
. "( " . $base_query . " ) AS base "
. " LEFT JOIN (" . $mtc_join_query . " ) AS mtc ON base.imsi = mtc.imsi "
. " LEFT JOIN (" . $moc_join_query . " ) AS moc ON base.imsi = moc.imsi " ;
Anti-Fraud in RDBMS
How did it feel…?
After moving to Mongo
● One main collection for 2 types (MOC & MTC)
● Aggregation framework is much more simple
After moving to Mongo
$base_match = array(
'$match' => array(
'source' => 'nrtrde',
'unified_record_time' => array('$gte' => new MongoDate($charge_time)),
)
);
$where = array(
'$match' => array(
'record_type' => 'MOC',
'connectedNumber' => array('$regex' => '^972'),
'event_stamp' => array('$exists' => false),
'deposit_stamp' => array('$exists' => false),
'callEventDurationRound' => array('$gt' => 0), // not sms
),
);
$group = array(
'$group' => array(
"_id" => '$imsi',
"moc_israel" => array('$sum' => '$callEventDurationRound'),
'lines_stamps' => array('$addToSet' => '$stamp'),
),
);
$project = array(
'$project' => array(
'imsi' => '$_id',
'_id' => 0,
'moc_israel' => 1,
'lines_stamps' => 1,
),
);
After moving to Mongo
$having = array(
'$match' => array(
'moc_israel' => array('$gte' => Billrun_Factory::config()->getConfigValue('nrtrde.thresholds.moc.israel'))
),
);
$moc_israel = $lines->aggregate($base_match, $where, $group, $project, $having);
//sms out to all numbers
$where['$match']['record_type'] = 'MOC';
$where['$match']['callEventDurationRound'] = 0;
$group['$group']['sms_out'] = $group['$group']['mtc_all'];
unset($group['$group']['mtc_all']);
unset($having['$match']['mtc_all']);
$group['$group']['sms_out'] = array('$sum' => 1);
$having['$match']['sms_out'] = array('$gte' => Billrun_Factory::config()->getConfigValue('nrtrde.thresholds.smsout'));
$project['$project']['sms_out'] = 1;
unset($project['$project']['mtc_all']);
$sms_out = $lines->aggregate($base_match, $where, $group, $project, $having);
What is billing?
● Group of processes of communications
service providers
● responsible to collect consumption data
● calculate charging and billing information
● produce bills to customers
● process their payments and manage debt
collection
Wikipedia
What is billing?
● This is how we see it
● The KISS way
Telecom today - database challenges
● Telecom situation world wide today:
○ Unlimited packages, extend 3g usage, with high
competition
○ High-volume - 4g, LTE
○ Different Events - different data structure
5 *main* data-structures (CDR) from different sources
● NSN - Calls
● SMSC - SMS
● MMSC - MMS
● GGSN - Data
● TAP3 - International usage
Billing and MongoDB - Pros
NSN Record
> db.lines.findOne({"usaget" : "call", aid:XXXXXXX})
{
"_id" : ObjectId("52bafd818f7ac3943a8b96dc"),
"stamp" : "87cea5dec484c8f6a19e44e77a2e15b4",
"record_type" : "01",
"record_number" : "13857000",
"record_status" : 0,
"exchange_id" : "000006270000",
"call_reference" : "700227d9a3",
"urt" : ISODate("2013-12-25T15:09:15Z"),
"charging_start_time" : "20131225170915",
"charging_end_time" : "20131225171517",
"call_reference_time" : "20131225170914",
"duration" : 362,
"calling_number" : "972546918666",
"called_number" : "26366667",
"call_type" : "3",
"chrg_type" : "0",
"called_imsi" : "000030000000000",
"imsi" : "000089000101076",
"in_circuit_group_name" : "",
"in_circuit_group" : "",
"out_circuit_group_name" : "NBZQZA8",
"out_circuit_group" : "0503",
"tariff_class" : "000000",
"called_number_ton" : "6",
"org_dur" : 362,
"type" : "nsn",
"source" : "binary",
"file" : "CF0322.DAT",
"log_stamp" : "0a3ffdb7c9ccc175e38be2fcc00f8c28",
"process_time" : "2013-12-25 17:35:22",
"usaget" : "call",
"usagev" : 362,
"arate" : DBRef("rates", ObjectId("521e07fcd88db0e73f0001c9")),
"aid" : XXXXXXX,
"sid" : YYYYY,
"plan" : "LARGE",
"aprice" : 0,
}
SMS Record
> db.lines.findOne({"usaget" : "sms", aid:XXXXXXX})
{
"_id" : ObjectId("52e52ff1d88db071648b4ad7"),
"stamp" : "9328f3aaa114aaba910910053a11b3e8",
"record_type" : "1",
"calling_number" : "000972546918666",
"calling_imsi" : "000089200000000",
"calling_msc" : "000972000000000",
"billable" : "000000000000000",
"called_number" : "000972547655380",
"called_imsi" : "425089109386379",
"called_msc" : "000972586279101",
"message_submition_time" : "140125192517",
"time_offest" : "02",
"message_delivery_time" : "140125192519",
"time_offest1" : "02",
"cause_of_terminition" : "100",
"call_reference" : "5137864939035049",
"message_length" : "050",
"concatenated" : "1",
"concatenated_from" : "09",
"source" : "separator_field_lines",
"type" : "smsc",
"log_stamp" : "a5950686e364d1400c13dd1857c3340e",
"file" : "140125192403_5735golan.cdr",
"process_time" : "2014-01-26 17:53:21",
"urt" : ISODate("2014-01-25T17:25:17Z"),
"usaget" : "sms",
"usagev" : 1,
"arate" : DBRef("rates", ObjectId("521e07fcd88db0e73f0001db")),
"aid" : XXXXXXX,
"sid" : YYYYY,
"plan" : "LARGE",
"aprice" : 0,
"usagesb" : 4,
"billrun" : "201402"
}
Data Record
> db.lines.findOne({"usaget" : "data", aid:XXXXXXX})
{
"_id" : ObjectId("539076678f7ac34a1d8b9367"),
"stamp" : "8a9f891ec85c5294c974a34653356055",
"imsi" : "400009209100000",
"served_imsi" : "400009209100000",
"ggsn_address" : "XX.XX.144.18",
"charging_id" : "2814645234",
"sgsn_address" : "XX.XX.145.9",
"served_pdp_address" : "XX.XX.237.95",
"urt" : ISODate("2014-06-05T09:34:47Z"),
"record_opening_time" : "20140605123447",
"ms_timezone" : "+03:00",
"node_id" : "GLTNGPT",
"served_msisdn" : "00002546918666",
"fbc_uplink_volume" : 61298,
"fbc_downlink_volume" : 217304,
"rating_group" : 0,
"type" : "ggsn",
"source" : "binary",
"file" : "GLTNGPT_-_0000056580.20140605_-_1251+0300",
"log_stamp" : "45a227ced1098bc76a44774eae04eb67",
"process_time" : "2014-06-05 16:39:40",
"usaget" : "data",
"usagev" : 278602,
"arate" : DBRef("rates", ObjectId("521e07fcd88db0e73f000200")),
"apr" : 0.020264916503503202,
"aid" : XXXXXXX,
"sid" : YYYYY,
"plan" : "LARGE",
"aprice" : 0,
"usagesb" : 478682116,
"billrun" : "201406"
}
TAP3 Record (intl roaming)
> db.lines.findOne({type:"tap3", aid:9073496})
{
"_id" : ObjectId("538d9ac98f7ac3e17d8b4fd6"),
"stamp" : "8f6cdc8662307ee2ed951ce640a585b5",
"basicCallInformation" : {
"GprsChargeableSubscriber" : {
"chargeableSubscriber" : {
"simChargeableSubscriber" : {
"imsi" : "400009209100000"
}
},
"pdpAddress" : "XX.XX.227.158"
},
"GprsDestination" : {
"AccessPointNameNI" : "internet.golantelecom.net.il"
},
"CallEventStartTimeStamp" : {
"localTimeStamp" : "20140529205131",
"TimeOffsetCode" : 0
},
"TotalCallEventDuration" : 163
},
"LocationInformation" : {
"gprsNetworkLocation" : {
"RecEntityCodeList" : {
"RecEntityCode" : [
"",
"u0000"
]
},
"LocationArea" : 00001,
"CellId" : 0001
},
"GeographicalLocation" : {
"ServingNetwork" : "MMMM"
}
},
"ImeiOrEsn" : false,
"GprsServiceUsed" : {
"DataVolumeIncoming" : 195120,
"DataVolumeOutgoing" : 48600,
"ChargeInformationList" : {
"ChargeInformation" : {
"ChargedItem" : "X",
"ExchangeRateCode" : 0,
"ChargeDetailList" : {
"ChargeDetail" : {
"ChargeType" : "00",
"Charge" : 001,
"ChargeableUnits" : 100000,
"ChargedUnits" : 100000,
"ChargeDetailTimeStamp" : {
"localTimeStamp" : "20140529205131",
"TimeOffset" : 0
}
}
}
}
}
},
"OperatorSpecInfoList" : {
"OperatorSpecInformation" : [
"00000000.0000",
"00000000.0000",
"00000000.0000"
]
},
"record_type" : "e",
"urt" : ISODate("2014-05-29T18:51:31Z"),
"tzoffset" : "+0200",
"imsi" : "400009209100000",
"serving_network" : "DEUE2",
"sdr" : 0.0001,
"exchange_rate" : 1.12078,
"type" : "tap3",
"file" : "CDBELHBISRGT02253",
"log_stamp" : "a0ad109c6e795f6c1feeef9ef649d937",
"process_time" : "2014-06-03 12:50:08",
"usaget" : "data",
"usagev" : 243720,
"arate" : DBRef("rates", ObjectId
("521e07fed88db0e73f000219")),
"apr" : 0.46640616,
"aid" : 9073496,
"sid" : 78288,
"plan" : "LARGE",
"out_plan" : 243720,
"aprice" : 0.46640616,
"usagesb" : 39139746,
"billrun" : "201406"
}
Billing and MongoDB - Pros
Loose coupling compared to traditional billing components
Old
w/o MongoDb New
with MongoDb
Billing and MongoDB - Pros
● One call can be spread on few CDRs
● BillRun merges records only on presentation
layer or export
● No DB-level aggregation nor accumulation
○ No need for mediation
● Use billing and monitoring CDR in one system
database
Billing and MongoDB - Pros
Sophisticated rating module
● Rating module depends on CDR structure
● Easy to implement recurring rating
Rate module example
MongoDB advantages with Billing
Invoice JSON2PDF process
● Use json as metadata for the PDF
● Easy to export
● Fast processing
MongoDB advantages with Billing
Invoice metadata
> db.billrun.findOne({billrun_key:"201405", aid:9073496})
{
"aid" : NumberLong(9073496),
"subs" : [
{
"sid" : NumberLong(78288),
"subscriber_status" : "open",
"current_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3dd")),
"next_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3dd")),
"kosher" : false,
"breakdown" : {
"in_plan" : {
"base" : {
"INTERNET_BILL_BY_VOLUME" : {
"totals" : {
"data" : {
"usagev" : NumberLong(1975547725),
"cost" : NumberLong(0),
"count" : NumberLong(1352)
}
},
"vat" : 0.18
},
"IL_MOBILE" : {
"totals" : {
"sms" : {
"usagev" : NumberLong(159),
"cost" : NumberLong(0),
"count" : NumberLong(159)
},
"call" : {
"usagev" : NumberLong(20788),
"cost" : NumberLong(0),
"count" : NumberLong(83)
}
},
"vat" : 0.18
},
"IL_FIX" : {
"totals" : {
"call" : {
"usagev" : NumberLong(1217),
"cost" : NumberLong(0),
"count" : NumberLong(16)
}
},
"vat" : 0.18
},
"INTERNAL_VOICE_MAIL_CALL" : {
"totals" : {
"call" : {
"usagev" : NumberLong(60),
"cost" : NumberLong(0),
"count" : NumberLong(2)
}
},
"vat" : 0.18
},
"service" : {
"cost" : 83.898305085,
"vat" : 0.18
}
},
"intl" : {
"KT_USA_NEW" : {
"totals" : {
"call" : {
"usagev" : NumberLong(149),
"cost" : NumberLong(0),
"count" : NumberLong(2)
}
},
"vat" : 0.18
}
}
},
MongoDB advantages with Billing
Invoice metadata
"credit" : {
"refund_vatable" : {
"CRM-REFUND_PROMOTION_1024-BILLRUN_201405" : -33.898305084746
}
}
},
"lines" : {
"data" : {
"counters" : {
"20140425" : {
"usagev" : NumberLong(11991615),
"aprice" : NumberLong(0),
"plan_flag" : "in"
},
…. /* data by date really long, so let’s cut it from this demonstration */
}
}
},
"totals" : {
"vatable" : 50.000000000254005,
"before_vat" : 50.000000000254005,
"after_vat" : 59.00000000029973
},
"costs" : {
"credit" : {
"refund" : {
"vatable" : -33.898305084746
}
},
"flat" : {
"vatable" : 83.898305085
}
}
},
{
"sid" : NumberLong(354961),
"subscriber_status" : "open",
"current_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3de")),
"next_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3de")),
"kosher" : false,
"breakdown" : {
"in_plan" : {
"base" : {
"service" : {
"cost" : 8.466101695,
"vat" : 0.18
}
}
}
},
"totals" : {
"vatable" : 8.466101695,
"before_vat" : 8.466101695,
"after_vat" : 9.9900000001
},
"costs" : {
"flat" : {
"vatable" : 8.466101695
}
}
}
],
"vat" : 0.18,
"billrun_key" : "201405",
"totals" : {
"before_vat" : 58.466101695254004,
"after_vat" : 68.99000000039973,
"vatable" : 58.466101695254004
},
"_id" : ObjectId("5382fd3cd88db0c31a8b74cc"),
"invoice_id" : NumberLong(14738102),
"invoice_file" : "201405_009073496_00014738102.xml"
}
Infrastructure
BETA
First Production
Today
Data center 1
Data center 2
Data center 1
Data center 2 Data center 1
Data center 2
Archive
App stack
BillRun application
BillRun core
PHP YAF
framework
Zend and more libraries
MongoDB
Web service Cli/Cron services
Mongodloid https://github.com/BillRun/Mongodloid
https://github.com/mongodb/mongo/
https://github.com/BillRun/system
https://github.com/zendframework/
https://github.com/twbs/bootstrap
https://github.com/laruence/php-yaf
Pay Attention! What to keep in mind
Transactional (tx) processes
● write concern - acknowledged (default in 2.4)
● findAndModify (A.K.A FAM) - document tx
● value=oldValue
● 2 phase commit - app side
● Transaction lock by design
Transaction workflow diagram
High performance tricks
● With SSD you get x20 more performance
● MongoDB loves RAM
● Follow MongoDB production notes
○ Readahead low as possible
○ THP - transparent hugepages
Pay Attention! What to keep in mind
More tips that happened to all
● Shorten property names
● MongoDB have database lock
○ Separate database for heavy-write collections
Pay Attention! What to keep in mind
TCO - MongoDB based solution
● 3 Months dev
● 3 Months QA
● Few days of maintenance infra and app
● Easy to add features
● Easy to scale
What can BillRun do
● 5,000 events per second
○ Including DB insert and transactional rating
● That means 157,680,000,000 events per year
● Create hundreds of millions invoices
Do not forget!
Thank you, Ofer Cohen
ofer@billrun.net
@oc666
Billing on Top of

More Related Content

What's hot

MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDBTakahiro Inoue
 
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB
 
MongoDB Performance Debugging
MongoDB Performance DebuggingMongoDB Performance Debugging
MongoDB Performance DebuggingMongoDB
 
MongoDB Europe 2016 - Debugging MongoDB Performance
MongoDB Europe 2016 - Debugging MongoDB PerformanceMongoDB Europe 2016 - Debugging MongoDB Performance
MongoDB Europe 2016 - Debugging MongoDB PerformanceMongoDB
 
ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~
ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~
ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~5 6
 
Schema design
Schema designSchema design
Schema designchristkv
 
20110514 mongo dbチューニング
20110514 mongo dbチューニング20110514 mongo dbチューニング
20110514 mongo dbチューニングYuichi Matsuo
 
GraphTalk Stockholm - Fraud Detection with Graphs
GraphTalk Stockholm - Fraud Detection with GraphsGraphTalk Stockholm - Fraud Detection with Graphs
GraphTalk Stockholm - Fraud Detection with GraphsNeo4j
 
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017BookNet Canada
 
Mongodb index 讀書心得
Mongodb index 讀書心得Mongodb index 讀書心得
Mongodb index 讀書心得cc liu
 
MongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 Link
MongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 LinkMongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 Link
MongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 LinkMongoDB
 
Mongodb debugging-performance-problems
Mongodb debugging-performance-problemsMongodb debugging-performance-problems
Mongodb debugging-performance-problemsMongoDB
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hacksteindistributed matters
 
GraphTalk Helsinki - Fraud Analysis with Neo4j
GraphTalk Helsinki - Fraud Analysis with Neo4jGraphTalk Helsinki - Fraud Analysis with Neo4j
GraphTalk Helsinki - Fraud Analysis with Neo4jNeo4j
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015NoSQLmatters
 

What's hot (20)

MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDB
 
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
Books
BooksBooks
Books
 
MongoDB Performance Debugging
MongoDB Performance DebuggingMongoDB Performance Debugging
MongoDB Performance Debugging
 
MongoDB Europe 2016 - Debugging MongoDB Performance
MongoDB Europe 2016 - Debugging MongoDB PerformanceMongoDB Europe 2016 - Debugging MongoDB Performance
MongoDB Europe 2016 - Debugging MongoDB Performance
 
ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~
ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~
ChromeからMacBookのTouchIDでWebAuthenticationする ~Idance vol1~
 
Schema design
Schema designSchema design
Schema design
 
Mongo db presentation
Mongo db presentationMongo db presentation
Mongo db presentation
 
20110514 mongo dbチューニング
20110514 mongo dbチューニング20110514 mongo dbチューニング
20110514 mongo dbチューニング
 
GraphTalk Stockholm - Fraud Detection with Graphs
GraphTalk Stockholm - Fraud Detection with GraphsGraphTalk Stockholm - Fraud Detection with Graphs
GraphTalk Stockholm - Fraud Detection with Graphs
 
Asssignment2
Asssignment2 Asssignment2
Asssignment2
 
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
Beyond Good & Evil: The nuts and bolts of DRM - Dave Cramer - ebookcraft 2017
 
Mongodb index 讀書心得
Mongodb index 讀書心得Mongodb index 讀書心得
Mongodb index 讀書心得
 
MongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 Link
MongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 LinkMongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 Link
MongoDB World 2019: Using Client Side Encryption in MongoDB 4.2 Link
 
Mongodb debugging-performance-problems
Mongodb debugging-performance-problemsMongodb debugging-performance-problems
Mongodb debugging-performance-problems
 
MongoDB Oplog入門
MongoDB Oplog入門MongoDB Oplog入門
MongoDB Oplog入門
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
 
GraphTalk Helsinki - Fraud Analysis with Neo4j
GraphTalk Helsinki - Fraud Analysis with Neo4jGraphTalk Helsinki - Fraud Analysis with Neo4j
GraphTalk Helsinki - Fraud Analysis with Neo4j
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
 

Viewers also liked

Webinar slides: Replication Topology Changes for MySQL and MariaDB
Webinar slides: Replication Topology Changes for MySQL and MariaDBWebinar slides: Replication Topology Changes for MySQL and MariaDB
Webinar slides: Replication Topology Changes for MySQL and MariaDBSeveralnines
 
Overview of Postgres 9.5
Overview of Postgres 9.5 Overview of Postgres 9.5
Overview of Postgres 9.5 EDB
 
(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDS
(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDS(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDS
(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDSAmazon Web Services
 
What's new in MySQL Cluster 7.4 webinar charts
What's new in MySQL Cluster 7.4 webinar chartsWhat's new in MySQL Cluster 7.4 webinar charts
What's new in MySQL Cluster 7.4 webinar chartsAndrew Morgan
 
The Complete MariaDB Server Tutorial - Percona Live 2015
The Complete MariaDB Server Tutorial - Percona Live 2015The Complete MariaDB Server Tutorial - Percona Live 2015
The Complete MariaDB Server Tutorial - Percona Live 2015Colin Charles
 
Performance improvements in PostgreSQL 9.5 and beyond
Performance improvements in PostgreSQL 9.5 and beyondPerformance improvements in PostgreSQL 9.5 and beyond
Performance improvements in PostgreSQL 9.5 and beyondTomas Vondra
 
PostgreSQL Streaming Replication Cheatsheet
PostgreSQL Streaming Replication CheatsheetPostgreSQL Streaming Replication Cheatsheet
PostgreSQL Streaming Replication CheatsheetAlexey Lesovsky
 
MongoDB on EC2 and EBS
MongoDB on EC2 and EBSMongoDB on EC2 and EBS
MongoDB on EC2 and EBSJared Rosoff
 
Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...
Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...
Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...Severalnines
 

Viewers also liked (10)

Webinar slides: Replication Topology Changes for MySQL and MariaDB
Webinar slides: Replication Topology Changes for MySQL and MariaDBWebinar slides: Replication Topology Changes for MySQL and MariaDB
Webinar slides: Replication Topology Changes for MySQL and MariaDB
 
Overview of Postgres 9.5
Overview of Postgres 9.5 Overview of Postgres 9.5
Overview of Postgres 9.5
 
(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDS
(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDS(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDS
(DAT209) NEW LAUNCH! Introducing MariaDB on Amazon RDS
 
What's new in MySQL Cluster 7.4 webinar charts
What's new in MySQL Cluster 7.4 webinar chartsWhat's new in MySQL Cluster 7.4 webinar charts
What's new in MySQL Cluster 7.4 webinar charts
 
The Complete MariaDB Server Tutorial - Percona Live 2015
The Complete MariaDB Server Tutorial - Percona Live 2015The Complete MariaDB Server Tutorial - Percona Live 2015
The Complete MariaDB Server Tutorial - Percona Live 2015
 
Performance improvements in PostgreSQL 9.5 and beyond
Performance improvements in PostgreSQL 9.5 and beyondPerformance improvements in PostgreSQL 9.5 and beyond
Performance improvements in PostgreSQL 9.5 and beyond
 
PostgreSQL Streaming Replication Cheatsheet
PostgreSQL Streaming Replication CheatsheetPostgreSQL Streaming Replication Cheatsheet
PostgreSQL Streaming Replication Cheatsheet
 
MongoDB on EC2 and EBS
MongoDB on EC2 and EBSMongoDB on EC2 and EBS
MongoDB on EC2 and EBS
 
Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...
Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...
Deep Dive Into How To Monitor MySQL or MariaDB Galera Cluster / Percona XtraD...
 
JSON By Example
JSON By ExampleJSON By Example
JSON By Example
 

Similar to MongoDB World 2014 - BillRun, Billing on top of MongoDB

Mongo db world 2014 billrun
Mongo db world 2014   billrunMongo db world 2014   billrun
Mongo db world 2014 billrunMongoDB
 
Cdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetupCdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetupchristkv
 
How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6Maxime Beugnet
 
MongoDB dla administratora
MongoDB dla administratora MongoDB dla administratora
MongoDB dla administratora 3camp
 
[MongoDB.local Bengaluru 2018] Keynote
[MongoDB.local Bengaluru 2018] Keynote[MongoDB.local Bengaluru 2018] Keynote
[MongoDB.local Bengaluru 2018] KeynoteMongoDB
 
Weather of the Century: Design and Performance
Weather of the Century: Design and PerformanceWeather of the Century: Design and Performance
Weather of the Century: Design and PerformanceMongoDB
 
PistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for AnalyticsPistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for AnalyticsAndrew Morgan
 
Using MongoDB As a Tick Database
Using MongoDB As a Tick DatabaseUsing MongoDB As a Tick Database
Using MongoDB As a Tick DatabaseMongoDB
 
A Century Of Weather Data - Midwest.io
A Century Of Weather Data - Midwest.ioA Century Of Weather Data - Midwest.io
A Century Of Weather Data - Midwest.ioRandall Hunt
 
Work in TDW
Work in TDWWork in TDW
Work in TDWsaso70
 
Operational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB WebinarOperational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB WebinarMongoDB
 
Webinar: Position and Trade Management with MongoDB
Webinar: Position and Trade Management with MongoDBWebinar: Position and Trade Management with MongoDB
Webinar: Position and Trade Management with MongoDBMongoDB
 
Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)
Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)
Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)Dan Robinson
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeWim Godden
 
Audit¢rio 09 mercado envios - novas funcionalidades - bruno elia
Audit¢rio 09   mercado envios - novas funcionalidades - bruno eliaAudit¢rio 09   mercado envios - novas funcionalidades - bruno elia
Audit¢rio 09 mercado envios - novas funcionalidades - bruno eliafsolari
 
How ShopperTrak Is Using MongoDB
How ShopperTrak Is Using MongoDBHow ShopperTrak Is Using MongoDB
How ShopperTrak Is Using MongoDBMongoDB
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeWim Godden
 
IOOF IT System Modernisation
IOOF IT System ModernisationIOOF IT System Modernisation
IOOF IT System ModernisationMongoDB
 
Beyond php it's not (just) about the code
Beyond php   it's not (just) about the codeBeyond php   it's not (just) about the code
Beyond php it's not (just) about the codeWim Godden
 

Similar to MongoDB World 2014 - BillRun, Billing on top of MongoDB (20)

Mongo db world 2014 billrun
Mongo db world 2014   billrunMongo db world 2014   billrun
Mongo db world 2014 billrun
 
Cdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetupCdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetup
 
How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6
 
MongoDB dla administratora
MongoDB dla administratora MongoDB dla administratora
MongoDB dla administratora
 
[MongoDB.local Bengaluru 2018] Keynote
[MongoDB.local Bengaluru 2018] Keynote[MongoDB.local Bengaluru 2018] Keynote
[MongoDB.local Bengaluru 2018] Keynote
 
Weather of the Century: Design and Performance
Weather of the Century: Design and PerformanceWeather of the Century: Design and Performance
Weather of the Century: Design and Performance
 
PistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for AnalyticsPistonHead's use of MongoDB for Analytics
PistonHead's use of MongoDB for Analytics
 
Using MongoDB As a Tick Database
Using MongoDB As a Tick DatabaseUsing MongoDB As a Tick Database
Using MongoDB As a Tick Database
 
A Century Of Weather Data - Midwest.io
A Century Of Weather Data - Midwest.ioA Century Of Weather Data - Midwest.io
A Century Of Weather Data - Midwest.io
 
Mongo db dla administratora
Mongo db dla administratoraMongo db dla administratora
Mongo db dla administratora
 
Work in TDW
Work in TDWWork in TDW
Work in TDW
 
Operational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB WebinarOperational Intelligence with MongoDB Webinar
Operational Intelligence with MongoDB Webinar
 
Webinar: Position and Trade Management with MongoDB
Webinar: Position and Trade Management with MongoDBWebinar: Position and Trade Management with MongoDB
Webinar: Position and Trade Management with MongoDB
 
Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)
Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)
Powering Heap With PostgreSQL And CitusDB (PGConf Silicon Valley 2015)
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
 
Audit¢rio 09 mercado envios - novas funcionalidades - bruno elia
Audit¢rio 09   mercado envios - novas funcionalidades - bruno eliaAudit¢rio 09   mercado envios - novas funcionalidades - bruno elia
Audit¢rio 09 mercado envios - novas funcionalidades - bruno elia
 
How ShopperTrak Is Using MongoDB
How ShopperTrak Is Using MongoDBHow ShopperTrak Is Using MongoDB
How ShopperTrak Is Using MongoDB
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the code
 
IOOF IT System Modernisation
IOOF IT System ModernisationIOOF IT System Modernisation
IOOF IT System Modernisation
 
Beyond php it's not (just) about the code
Beyond php   it's not (just) about the codeBeyond php   it's not (just) about the code
Beyond php it's not (just) about the code
 

More from Ofer Cohen

BillRun Docker Introduction
BillRun Docker IntroductionBillRun Docker Introduction
BillRun Docker IntroductionOfer Cohen
 
BillRun and Joomla - How is Joomla relate to billing system
BillRun and Joomla - How is Joomla relate to billing systemBillRun and Joomla - How is Joomla relate to billing system
BillRun and Joomla - How is Joomla relate to billing systemOfer Cohen
 
Proposals, contracts and clients for web developers - Ofer Cohen
Proposals, contracts and clients for web developers - Ofer CohenProposals, contracts and clients for web developers - Ofer Cohen
Proposals, contracts and clients for web developers - Ofer CohenOfer Cohen
 
Joomla!Day Poland 2013 - Joomla Architecture (Ofer Cohen)
Joomla!Day Poland 2013 - Joomla Architecture  (Ofer Cohen)Joomla!Day Poland 2013 - Joomla Architecture  (Ofer Cohen)
Joomla!Day Poland 2013 - Joomla Architecture (Ofer Cohen)Ofer Cohen
 
Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...
Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...
Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...Ofer Cohen
 
Wordcamp Jerusalem 2013 - what if Wordpress was not open source
Wordcamp Jerusalem 2013 - what if Wordpress was not open sourceWordcamp Jerusalem 2013 - what if Wordpress was not open source
Wordcamp Jerusalem 2013 - what if Wordpress was not open sourceOfer Cohen
 
Joomla!Day 2013 India
Joomla!Day 2013 IndiaJoomla!Day 2013 India
Joomla!Day 2013 IndiaOfer Cohen
 
Joomla!Day Israel 2012 - The business of Joomla
Joomla!Day Israel 2012 - The business of JoomlaJoomla!Day Israel 2012 - The business of Joomla
Joomla!Day Israel 2012 - The business of JoomlaOfer Cohen
 
וורדפרס, ג'ומלה, דרופל וכל מה שביניהם‏
וורדפרס, ג'ומלה, דרופל  וכל מה שביניהם‏וורדפרס, ג'ומלה, דרופל  וכל מה שביניהם‏
וורדפרס, ג'ומלה, דרופל וכל מה שביניהם‏Ofer Cohen
 
ג'ומלה ישראל - ותיקים מדריכים חדשים
ג'ומלה ישראל - ותיקים מדריכים חדשיםג'ומלה ישראל - ותיקים מדריכים חדשים
ג'ומלה ישראל - ותיקים מדריכים חדשיםOfer Cohen
 
Jab12 - Joomla! architecture revealed
Jab12 - Joomla! architecture revealedJab12 - Joomla! architecture revealed
Jab12 - Joomla! architecture revealedOfer Cohen
 
Israel Joomla! 1.6 Party
Israel Joomla! 1.6 PartyIsrael Joomla! 1.6 Party
Israel Joomla! 1.6 PartyOfer Cohen
 

More from Ofer Cohen (12)

BillRun Docker Introduction
BillRun Docker IntroductionBillRun Docker Introduction
BillRun Docker Introduction
 
BillRun and Joomla - How is Joomla relate to billing system
BillRun and Joomla - How is Joomla relate to billing systemBillRun and Joomla - How is Joomla relate to billing system
BillRun and Joomla - How is Joomla relate to billing system
 
Proposals, contracts and clients for web developers - Ofer Cohen
Proposals, contracts and clients for web developers - Ofer CohenProposals, contracts and clients for web developers - Ofer Cohen
Proposals, contracts and clients for web developers - Ofer Cohen
 
Joomla!Day Poland 2013 - Joomla Architecture (Ofer Cohen)
Joomla!Day Poland 2013 - Joomla Architecture  (Ofer Cohen)Joomla!Day Poland 2013 - Joomla Architecture  (Ofer Cohen)
Joomla!Day Poland 2013 - Joomla Architecture (Ofer Cohen)
 
Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...
Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...
Joomla!Day Poland 2013 - Joomla and Open Source - How it works and how can I ...
 
Wordcamp Jerusalem 2013 - what if Wordpress was not open source
Wordcamp Jerusalem 2013 - what if Wordpress was not open sourceWordcamp Jerusalem 2013 - what if Wordpress was not open source
Wordcamp Jerusalem 2013 - what if Wordpress was not open source
 
Joomla!Day 2013 India
Joomla!Day 2013 IndiaJoomla!Day 2013 India
Joomla!Day 2013 India
 
Joomla!Day Israel 2012 - The business of Joomla
Joomla!Day Israel 2012 - The business of JoomlaJoomla!Day Israel 2012 - The business of Joomla
Joomla!Day Israel 2012 - The business of Joomla
 
וורדפרס, ג'ומלה, דרופל וכל מה שביניהם‏
וורדפרס, ג'ומלה, דרופל  וכל מה שביניהם‏וורדפרס, ג'ומלה, דרופל  וכל מה שביניהם‏
וורדפרס, ג'ומלה, דרופל וכל מה שביניהם‏
 
ג'ומלה ישראל - ותיקים מדריכים חדשים
ג'ומלה ישראל - ותיקים מדריכים חדשיםג'ומלה ישראל - ותיקים מדריכים חדשים
ג'ומלה ישראל - ותיקים מדריכים חדשים
 
Jab12 - Joomla! architecture revealed
Jab12 - Joomla! architecture revealedJab12 - Joomla! architecture revealed
Jab12 - Joomla! architecture revealed
 
Israel Joomla! 1.6 Party
Israel Joomla! 1.6 PartyIsrael Joomla! 1.6 Party
Israel Joomla! 1.6 Party
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 

Recently uploaded (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

MongoDB World 2014 - BillRun, Billing on top of MongoDB

  • 1. MongoDB World 2014 by S.D.O.C. Ltd. Billing on top of MongoDB Ofer Cohen
  • 2. Who Am I ? ● Open source evangelist ● Former Board member of OpenSourceMatters (Non-profit organization behind Joomla) ● S.D.O.C. Ltd. Co-Founder
  • 3. FUD ● FUD: Fear, Uncertainty and Doubt ● Tactic used in sales, marketing, public relations, politics and propaganda. Wikipedia
  • 4. FUD
  • 5. Preferred name for the presentation
  • 6. S.D.O.C. Ltd. vision We increase business success through great open source technologies and services ○ Open & Transparent ○ Don't reinvent the wheel ○ High Quality ○ Lean & Effective
  • 7. How did we get to billing (history) ● Client: Golan Telecom (Israel)
  • 8. How did we get to billing (history) ● Client: Golan Telecom ○ New & lean player in the market ○ 0=>~1M subscribers in few years ○ Limited resources & loves open source
  • 9. How did we get to billing (history) ● Client: Golan Telecom ○ Start up environment from Day 1 ○ Short and aggressive time to market ○ Unlimited plan for ~25$ ○ Customer can do almost everything using the website ■ Obviously requires 24/7 uptime
  • 10. How did we get to billing (history) ● Start with Anti-Fraud solution ● 2 Different data structure, 2 separated tables ○ Outgoing calls (MOC) ○ incoming calls (MTC) ○ SMS (duration=0 means SMS)
  • 11. Anti-Fraud in RDBMS How did it look like? Example code... $base_query = "SELECT imsi FROM moc WHERE callEventStartTimeStamp >=" . $start . " UNION SELECT imsi FROM mtc WHERE callEventStartTimeStamp >=" . $start $base_query = "SELECT imsi FROM (" . $base_query . ") AS qry "; if (isset($args['imsi'])) $base_query .= "WHERE imsi = '" . $this->_connection->real_escape_string($args['imsi']) . "'"; $base_query .= "GROUP BY imsi "; $mtc_join_query = "SELECT 'mtc' AS type, imsi, SUM(callEventDuration) AS duration, SUM(CEILING(callEventDuration/60)*60) AS duration_round " . ", SUM(chargeAmount) charge " . ", SUM(IF(SUBSTRING(callingNumber, 1, 3)='972', callEventDuration, IF(CHAR_LENGTH(callingNumber)<=10, callEventDuration, 0))) AS israel_duration " . ", SUM(IF(SUBSTRING(callingNumber, 1, 3)='972', CEILING(callEventDuration/60)*60, IF(CHAR_LENGTH(callingNumber)<=10, CEILING (callEventDuration/60)*60, 0))) AS israel_duration_round " . ", SUM(IF(SUBSTRING(callingNumber, 1, 3)!='972', IF(CHAR_LENGTH(callingNumber)>10, callEventDuration, 0), 0)) AS non_israel_duration " . ", SUM(IF(SUBSTRING(callingNumber, 1, 3)!='972', IF(CHAR_LENGTH(callingNumber)>10, CEILING(callEventDuration/60)*60, 0), 0)) AS non_israel_duration_round " . ", SUM(IF(callEventDuration = 0, 1, 0)) AS sms_count "
  • 12. Anti-Fraud in RDBMS How did it look like? Example code... . "FROM mtc " . "WHERE callEventStartTimeStamp >=" . $start . " " . "GROUP BY type, imsi"; $moc_join_query = "SELECT 'moc' AS type, imsi, SUM(callEventDuration) AS duration, SUM(CEILING(callEventDuration/60)*60) AS duration_round " . ", SUM(chargeAmount) charge " . ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)='972', callEventDuration, IF(CHAR_LENGTH(connectedNumber)<=10, callEventDuration, 0))) AS israel_duration " . ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)='972', CEILING(callEventDuration/60)*60, IF(CHAR_LENGTH(connectedNumber)<=10, CEILING (callEventDuration/60)*60, 0))) AS israel_duration_round " . ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)!='972', IF(CHAR_LENGTH(connectedNumber)>10, callEventDuration, 0), 0)) AS non_israel_duration " . ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)!='972', IF(CHAR_LENGTH(connectedNumber)>10, CEILING(callEventDuration/60)*60, 0), 0)) AS non_israel_duration_round " . ", SUM(IF(callEventDuration = 0, 1, 0)) AS sms_count " . "FROM moc " . "WHERE callEventStartTimeStamp >=" . $start . " " . "GROUP BY type, imsi";
  • 13. Anti-Fraud in RDBMS How did it look like? Example code... $group_query = "SELECT base.imsi, moc.duration AS moc_duration, moc.charge AS moc_charge, " . "mtc.duration AS mtc_duration, mtc.charge AS mtc_charge, " . "mtc.duration_round AS mtc_duration_round, moc.duration_round AS moc_duration_round, " . "moc.israel_duration AS moc_israel_duration, moc.non_israel_duration AS moc_non_israel_duration, " . "moc.israel_duration_round AS moc_israel_duration_round, moc.non_israel_duration_round AS moc_non_israel_duration_round, " . "mtc.israel_duration AS mtc_israel_duration, mtc.non_israel_duration AS mtc_non_israel_duration, " . "mtc.israel_duration_round AS mtc_israel_duration_round, mtc.non_israel_duration_round AS mtc_non_israel_duration_round, " . "mtc.sms_count AS mtc_sms_count, moc.sms_count AS moc_sms_count " . "FROM " . "( " . $base_query . " ) AS base " . " LEFT JOIN (" . $mtc_join_query . " ) AS mtc ON base.imsi = mtc.imsi " . " LEFT JOIN (" . $moc_join_query . " ) AS moc ON base.imsi = moc.imsi " ;
  • 14. Anti-Fraud in RDBMS How did it feel…?
  • 15. After moving to Mongo ● One main collection for 2 types (MOC & MTC) ● Aggregation framework is much more simple
  • 16. After moving to Mongo $base_match = array( '$match' => array( 'source' => 'nrtrde', 'unified_record_time' => array('$gte' => new MongoDate($charge_time)), ) ); $where = array( '$match' => array( 'record_type' => 'MOC', 'connectedNumber' => array('$regex' => '^972'), 'event_stamp' => array('$exists' => false), 'deposit_stamp' => array('$exists' => false), 'callEventDurationRound' => array('$gt' => 0), // not sms ), ); $group = array( '$group' => array( "_id" => '$imsi', "moc_israel" => array('$sum' => '$callEventDurationRound'), 'lines_stamps' => array('$addToSet' => '$stamp'), ), ); $project = array( '$project' => array( 'imsi' => '$_id', '_id' => 0, 'moc_israel' => 1, 'lines_stamps' => 1, ), );
  • 17. After moving to Mongo $having = array( '$match' => array( 'moc_israel' => array('$gte' => Billrun_Factory::config()->getConfigValue('nrtrde.thresholds.moc.israel')) ), ); $moc_israel = $lines->aggregate($base_match, $where, $group, $project, $having); //sms out to all numbers $where['$match']['record_type'] = 'MOC'; $where['$match']['callEventDurationRound'] = 0; $group['$group']['sms_out'] = $group['$group']['mtc_all']; unset($group['$group']['mtc_all']); unset($having['$match']['mtc_all']); $group['$group']['sms_out'] = array('$sum' => 1); $having['$match']['sms_out'] = array('$gte' => Billrun_Factory::config()->getConfigValue('nrtrde.thresholds.smsout')); $project['$project']['sms_out'] = 1; unset($project['$project']['mtc_all']); $sms_out = $lines->aggregate($base_match, $where, $group, $project, $having);
  • 18. What is billing? ● Group of processes of communications service providers ● responsible to collect consumption data ● calculate charging and billing information ● produce bills to customers ● process their payments and manage debt collection Wikipedia
  • 19. What is billing? ● This is how we see it ● The KISS way
  • 20. Telecom today - database challenges ● Telecom situation world wide today: ○ Unlimited packages, extend 3g usage, with high competition ○ High-volume - 4g, LTE ○ Different Events - different data structure
  • 21. 5 *main* data-structures (CDR) from different sources ● NSN - Calls ● SMSC - SMS ● MMSC - MMS ● GGSN - Data ● TAP3 - International usage Billing and MongoDB - Pros
  • 22. NSN Record > db.lines.findOne({"usaget" : "call", aid:XXXXXXX}) { "_id" : ObjectId("52bafd818f7ac3943a8b96dc"), "stamp" : "87cea5dec484c8f6a19e44e77a2e15b4", "record_type" : "01", "record_number" : "13857000", "record_status" : 0, "exchange_id" : "000006270000", "call_reference" : "700227d9a3", "urt" : ISODate("2013-12-25T15:09:15Z"), "charging_start_time" : "20131225170915", "charging_end_time" : "20131225171517", "call_reference_time" : "20131225170914", "duration" : 362, "calling_number" : "972546918666", "called_number" : "26366667", "call_type" : "3", "chrg_type" : "0", "called_imsi" : "000030000000000", "imsi" : "000089000101076", "in_circuit_group_name" : "", "in_circuit_group" : "", "out_circuit_group_name" : "NBZQZA8", "out_circuit_group" : "0503", "tariff_class" : "000000", "called_number_ton" : "6", "org_dur" : 362, "type" : "nsn", "source" : "binary", "file" : "CF0322.DAT", "log_stamp" : "0a3ffdb7c9ccc175e38be2fcc00f8c28", "process_time" : "2013-12-25 17:35:22", "usaget" : "call", "usagev" : 362, "arate" : DBRef("rates", ObjectId("521e07fcd88db0e73f0001c9")), "aid" : XXXXXXX, "sid" : YYYYY, "plan" : "LARGE", "aprice" : 0, }
  • 23. SMS Record > db.lines.findOne({"usaget" : "sms", aid:XXXXXXX}) { "_id" : ObjectId("52e52ff1d88db071648b4ad7"), "stamp" : "9328f3aaa114aaba910910053a11b3e8", "record_type" : "1", "calling_number" : "000972546918666", "calling_imsi" : "000089200000000", "calling_msc" : "000972000000000", "billable" : "000000000000000", "called_number" : "000972547655380", "called_imsi" : "425089109386379", "called_msc" : "000972586279101", "message_submition_time" : "140125192517", "time_offest" : "02", "message_delivery_time" : "140125192519", "time_offest1" : "02", "cause_of_terminition" : "100", "call_reference" : "5137864939035049", "message_length" : "050", "concatenated" : "1", "concatenated_from" : "09", "source" : "separator_field_lines", "type" : "smsc", "log_stamp" : "a5950686e364d1400c13dd1857c3340e", "file" : "140125192403_5735golan.cdr", "process_time" : "2014-01-26 17:53:21", "urt" : ISODate("2014-01-25T17:25:17Z"), "usaget" : "sms", "usagev" : 1, "arate" : DBRef("rates", ObjectId("521e07fcd88db0e73f0001db")), "aid" : XXXXXXX, "sid" : YYYYY, "plan" : "LARGE", "aprice" : 0, "usagesb" : 4, "billrun" : "201402" }
  • 24. Data Record > db.lines.findOne({"usaget" : "data", aid:XXXXXXX}) { "_id" : ObjectId("539076678f7ac34a1d8b9367"), "stamp" : "8a9f891ec85c5294c974a34653356055", "imsi" : "400009209100000", "served_imsi" : "400009209100000", "ggsn_address" : "XX.XX.144.18", "charging_id" : "2814645234", "sgsn_address" : "XX.XX.145.9", "served_pdp_address" : "XX.XX.237.95", "urt" : ISODate("2014-06-05T09:34:47Z"), "record_opening_time" : "20140605123447", "ms_timezone" : "+03:00", "node_id" : "GLTNGPT", "served_msisdn" : "00002546918666", "fbc_uplink_volume" : 61298, "fbc_downlink_volume" : 217304, "rating_group" : 0, "type" : "ggsn", "source" : "binary", "file" : "GLTNGPT_-_0000056580.20140605_-_1251+0300", "log_stamp" : "45a227ced1098bc76a44774eae04eb67", "process_time" : "2014-06-05 16:39:40", "usaget" : "data", "usagev" : 278602, "arate" : DBRef("rates", ObjectId("521e07fcd88db0e73f000200")), "apr" : 0.020264916503503202, "aid" : XXXXXXX, "sid" : YYYYY, "plan" : "LARGE", "aprice" : 0, "usagesb" : 478682116, "billrun" : "201406" }
  • 25. TAP3 Record (intl roaming) > db.lines.findOne({type:"tap3", aid:9073496}) { "_id" : ObjectId("538d9ac98f7ac3e17d8b4fd6"), "stamp" : "8f6cdc8662307ee2ed951ce640a585b5", "basicCallInformation" : { "GprsChargeableSubscriber" : { "chargeableSubscriber" : { "simChargeableSubscriber" : { "imsi" : "400009209100000" } }, "pdpAddress" : "XX.XX.227.158" }, "GprsDestination" : { "AccessPointNameNI" : "internet.golantelecom.net.il" }, "CallEventStartTimeStamp" : { "localTimeStamp" : "20140529205131", "TimeOffsetCode" : 0 }, "TotalCallEventDuration" : 163 }, "LocationInformation" : { "gprsNetworkLocation" : { "RecEntityCodeList" : { "RecEntityCode" : [ "", "u0000" ] }, "LocationArea" : 00001, "CellId" : 0001 }, "GeographicalLocation" : { "ServingNetwork" : "MMMM" } }, "ImeiOrEsn" : false, "GprsServiceUsed" : { "DataVolumeIncoming" : 195120, "DataVolumeOutgoing" : 48600, "ChargeInformationList" : { "ChargeInformation" : { "ChargedItem" : "X", "ExchangeRateCode" : 0, "ChargeDetailList" : { "ChargeDetail" : { "ChargeType" : "00", "Charge" : 001, "ChargeableUnits" : 100000, "ChargedUnits" : 100000, "ChargeDetailTimeStamp" : { "localTimeStamp" : "20140529205131", "TimeOffset" : 0 } } } } } }, "OperatorSpecInfoList" : { "OperatorSpecInformation" : [ "00000000.0000", "00000000.0000", "00000000.0000" ] }, "record_type" : "e", "urt" : ISODate("2014-05-29T18:51:31Z"), "tzoffset" : "+0200", "imsi" : "400009209100000", "serving_network" : "DEUE2", "sdr" : 0.0001, "exchange_rate" : 1.12078, "type" : "tap3", "file" : "CDBELHBISRGT02253", "log_stamp" : "a0ad109c6e795f6c1feeef9ef649d937", "process_time" : "2014-06-03 12:50:08", "usaget" : "data", "usagev" : 243720, "arate" : DBRef("rates", ObjectId ("521e07fed88db0e73f000219")), "apr" : 0.46640616, "aid" : 9073496, "sid" : 78288, "plan" : "LARGE", "out_plan" : 243720, "aprice" : 0.46640616, "usagesb" : 39139746, "billrun" : "201406" }
  • 26. Billing and MongoDB - Pros Loose coupling compared to traditional billing components Old w/o MongoDb New with MongoDb
  • 27. Billing and MongoDB - Pros ● One call can be spread on few CDRs ● BillRun merges records only on presentation layer or export ● No DB-level aggregation nor accumulation ○ No need for mediation ● Use billing and monitoring CDR in one system database
  • 28. Billing and MongoDB - Pros Sophisticated rating module ● Rating module depends on CDR structure ● Easy to implement recurring rating
  • 30. MongoDB advantages with Billing Invoice JSON2PDF process ● Use json as metadata for the PDF ● Easy to export ● Fast processing
  • 31. MongoDB advantages with Billing Invoice metadata > db.billrun.findOne({billrun_key:"201405", aid:9073496}) { "aid" : NumberLong(9073496), "subs" : [ { "sid" : NumberLong(78288), "subscriber_status" : "open", "current_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3dd")), "next_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3dd")), "kosher" : false, "breakdown" : { "in_plan" : { "base" : { "INTERNET_BILL_BY_VOLUME" : { "totals" : { "data" : { "usagev" : NumberLong(1975547725), "cost" : NumberLong(0), "count" : NumberLong(1352) } }, "vat" : 0.18 }, "IL_MOBILE" : { "totals" : { "sms" : { "usagev" : NumberLong(159), "cost" : NumberLong(0), "count" : NumberLong(159) }, "call" : { "usagev" : NumberLong(20788), "cost" : NumberLong(0), "count" : NumberLong(83) } }, "vat" : 0.18 }, "IL_FIX" : { "totals" : { "call" : { "usagev" : NumberLong(1217), "cost" : NumberLong(0), "count" : NumberLong(16) } }, "vat" : 0.18 }, "INTERNAL_VOICE_MAIL_CALL" : { "totals" : { "call" : { "usagev" : NumberLong(60), "cost" : NumberLong(0), "count" : NumberLong(2) } }, "vat" : 0.18 }, "service" : { "cost" : 83.898305085, "vat" : 0.18 } }, "intl" : { "KT_USA_NEW" : { "totals" : { "call" : { "usagev" : NumberLong(149), "cost" : NumberLong(0), "count" : NumberLong(2) } }, "vat" : 0.18 } } },
  • 32. MongoDB advantages with Billing Invoice metadata "credit" : { "refund_vatable" : { "CRM-REFUND_PROMOTION_1024-BILLRUN_201405" : -33.898305084746 } } }, "lines" : { "data" : { "counters" : { "20140425" : { "usagev" : NumberLong(11991615), "aprice" : NumberLong(0), "plan_flag" : "in" }, …. /* data by date really long, so let’s cut it from this demonstration */ } } }, "totals" : { "vatable" : 50.000000000254005, "before_vat" : 50.000000000254005, "after_vat" : 59.00000000029973 }, "costs" : { "credit" : { "refund" : { "vatable" : -33.898305084746 } }, "flat" : { "vatable" : 83.898305085 } } }, { "sid" : NumberLong(354961), "subscriber_status" : "open", "current_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3de")), "next_plan" : DBRef("plans", ObjectId("51bd8dc9eb2f76d2178dd3de")), "kosher" : false, "breakdown" : { "in_plan" : { "base" : { "service" : { "cost" : 8.466101695, "vat" : 0.18 } } } }, "totals" : { "vatable" : 8.466101695, "before_vat" : 8.466101695, "after_vat" : 9.9900000001 }, "costs" : { "flat" : { "vatable" : 8.466101695 } } } ], "vat" : 0.18, "billrun_key" : "201405", "totals" : { "before_vat" : 58.466101695254004, "after_vat" : 68.99000000039973, "vatable" : 58.466101695254004 }, "_id" : ObjectId("5382fd3cd88db0c31a8b74cc"), "invoice_id" : NumberLong(14738102), "invoice_file" : "201405_009073496_00014738102.xml" }
  • 33. Infrastructure BETA First Production Today Data center 1 Data center 2 Data center 1 Data center 2 Data center 1 Data center 2 Archive
  • 34. App stack BillRun application BillRun core PHP YAF framework Zend and more libraries MongoDB Web service Cli/Cron services Mongodloid https://github.com/BillRun/Mongodloid https://github.com/mongodb/mongo/ https://github.com/BillRun/system https://github.com/zendframework/ https://github.com/twbs/bootstrap https://github.com/laruence/php-yaf
  • 35. Pay Attention! What to keep in mind Transactional (tx) processes ● write concern - acknowledged (default in 2.4) ● findAndModify (A.K.A FAM) - document tx ● value=oldValue ● 2 phase commit - app side ● Transaction lock by design
  • 37. High performance tricks ● With SSD you get x20 more performance ● MongoDB loves RAM ● Follow MongoDB production notes ○ Readahead low as possible ○ THP - transparent hugepages Pay Attention! What to keep in mind
  • 38. More tips that happened to all ● Shorten property names ● MongoDB have database lock ○ Separate database for heavy-write collections Pay Attention! What to keep in mind
  • 39. TCO - MongoDB based solution ● 3 Months dev ● 3 Months QA ● Few days of maintenance infra and app ● Easy to add features ● Easy to scale
  • 40. What can BillRun do ● 5,000 events per second ○ Including DB insert and transactional rating ● That means 157,680,000,000 events per year ● Create hundreds of millions invoices
  • 42. Thank you, Ofer Cohen ofer@billrun.net @oc666 Billing on Top of