SlideShare a Scribd company logo
1 of 36
Download to read offline
MongoDB Stitch Tutorial
Deep Dive on MongoDB Serverless
This presentation contains “forward-looking statements” within the meaning of Section 27A of the Securities Act of 1933,
as amended, and Section 21E of the Securities Exchange Act of 1934, as amended. Such forward-looking statements are
subject to a number of risks, uncertainties, assumptions and other factors that could cause actual results and the timing of
certain events to differ materially from future results expressed or implied by the forward-looking statements. Factors that
could cause or contribute to such differences include, but are not limited to, those identified our filings with the Securities
and Exchange Commission. You should not rely upon forward-looking statements as predictions of future events.
Furthermore, such forward-looking statements speak only as of the date of this presentation.
In particular, the development, release, and timing of any features or functionality described for MongoDB products
remains at MongoDB’s sole discretion. This information is merely intended to outline our general product direction and it
should not be relied on in making a purchasing decision nor is this a commitment, promise or legal obligation to deliver
any material, code, or functionality. Except as required by law, we undertake no obligation to update any forward-looking
statements to reflect events or circumstances after the date of such statements.
Safe Harbor Statement
Jason Flax
Senior Engineer
Stitch
Stitch
Stitch: What is it?
• Provide an interface for users to interact
with your app.
• Handle user actions and send requests to
the app server.
• Authenticate users and allow them to use
app features.
• Handle data requests and execute
business logic.
• Store and search persisted application
data.
• Manage data integrity, consistency, and
availability.
Stitch SDK
Packages the entire mobile stack together
Stitches the frontend and backend together
• End-to-end Mobile SDK
• API for local storage
• API for remote Stitch service invocation
• API for syncing between local and remote
• Provides a transparent bridge for applications
iOS SDK: https://github.com/mongodb/stitch-ios-sdk/
Android SDK: https://github.com/mongodb/stitch-android-sdk/
final StitchAppClient client = Stitch.getDefaultAppClient();
final MongoClient mongoClient = client.getServiceClient(LocalMongoDbService.ClientFactory);
MongoCollection<Document> items =
mongoClient.getDatabase(TodoItem.TODO_LIST_DATABASE).getCollection(TodoItem.TODO_LIST_COLLE
CTION);
public void updateChecked(final ObjectId itemId, final boolean isChecked) {
final Document updateDoc = new Document("$set", new Document(TodoItem.CHECKED_KEY, isChecked));
if (isChecked) {
updateDoc.append("$currentDate", new Document(TodoItem.DONE_DATE_KEY, true));
} else {
updateDoc.append("$unset", new Document(TodoItem.DONE_DATE_KEY, ""));
}
items.updateOne(new Document(TodoItem.ID_KEY, itemId), updateDoc);
...
}
private List<TodoItem> getItems() {
final ArrayList<TodoItem> todoItems = new ArrayList<>();
for (final Document doc : items.find()) {
if (TodoItem.isTodoItem(doc)) {
final TodoItem item = new TodoItem(doc);
todoItems.add(item);
}
}
return todoItems;
}
Stitch
Let’s build a chat app
User Authentication
Built-In Identity Providers
• Anonymous
• Email / Password
• OAuth 2.0 (Facebook & Google)
• API Key (Server & User)
• Custom (Bring Your Own Auth)
Application Users
• Associated with one or more identities
• Must authenticate to send requests
• Trigger authentication events
Custom User
/**
* The customer user object relative to our Stitch user that contains
* extended profile information.
*
* @param _id {String} the id of the associated Stitch user
* @param name {String} the chosen username of this user
* @param defaultAvatarOrdinal {Number} 0-7 the default avatar we choose for this user
* @param avatar {Binary?} the uploaded avatar for this user
* @param channelsSubscribedTo {StringArray} the channels this user is subscribed to
*/
export function User(_id, name, defaultAvatarOrdinal, avatar, channelsSubscribedTo) {
return {
_id, name, defaultAvatarOrdinal, avatar, channelsSubscribedTo
};
}
Server-Side Rules
Declarative Expressions
• Specify rule conditions with a document
• Access specific request/document values.
Dynamic Evaluation
• Add complex and/or personalized rules with
expansions and operators.
Secure by Default
• If an action does not pass any rule, Stitch
prevents the action
LoginView
export default class LoginView
extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
};
}
updateInputValue(evt) {
this.setState({
inputValue: evt.target.value
});
}
render() {
return (
<ChatLayout>
<LinearLayout>
<ChitChat>chit chat</ChitChat>
<Block />
<LoginInput placeholder="username"
style={{marginBottom: 20 + "px"}}
value={this.state.inputValue}
onChange={evt =>
this.updateInputValue(evt)} />
<LoginButton onClick={async () =>
await this.onLogin()}>login</LoginButton>
</LinearLayout>
</ChatLayout>
);
}
async onLogin() {
if (this.state.inputValue.length < 3) {
return
}
const stitchUser = await client.auth.loginWithCredential(new AnonymousCredential());
await usersCollection.insertOne(
EJSON.serialize(User(
stitchUser.id,
this.state.inputValue,
Math.floor(Math.random() * Math.floor(7)),
null,
["default"]
)));
const rootElement = document.getElementById("root");
ReactDOM.render(<ChatRoom />, rootElement);
}
ChannelSubscription
/**
* A vector clock that notifies us when a new message has been sent.
*
* @param _id {ObjectId} the unique id of this subscription
* @param ownerId {String} the user id of the owner of this subscription
* @param deviceId {String} the device id of the owner of this subscription
* @param localTimestamp {Numer} the local logical time
* @param remoteTimestamp {Number} the remote logical time
*/
export function ChannelSubscription(_id, channelId, ownerId, subscriptionId, localTimestamp,
remoteTimestamp) {
return {
_id, channelId, ownerId, deviceId: subscriptionId, localTimestamp, remoteTimestamp
};
}
ChannelMessage
/**
* A message one would send to a channel.
*
* @param _id {ObjectId} the unique id of the message
* @param channelId {String} the id of the channel this was sent to
* @param content {String} the actual text of the message
* @param sentAt {Number} the time the message was sent to the server or the time the
message hit the server
* @param remoteTimestamp {Number} the logical time of the message (to be updated by the
server trigger)
*/
export function ChannelMessage(_id, ownerId, channelId, content, sentAt, remoteTimestamp) {
return { _id, ownerId, channelId, content, sentAt, remoteTimestamp };
}
ChatRoom
export default class ChatRoom
extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
messages: [],
messageText: ""
}
}
componentDidMount() {
this.subscribeToChannel();
}
render() {
return <ChatLayout>
<ChatFeed messages={this.state.messages} />
<ChatBar sendMessage={text =>
this.sendMessage(text)}
setMessageText={(txt) => {
this.state.messageText = txt
this.setState(this.state)
}}
messageText={this.state.messageText}
/>
</ChatLayout>;
}
}
ChannelMessageObserver
export class ChannelMessageObserver extends Observable {
async sync(ids) {
if (this.stream) {
this.stream.close();
}
(await channelMessagesCollection.find({_id: { $in: ids }}).asArray()).forEach((msg) => {
this.notify({fullDocument: msg, operationType: "insert"})
});
this.stream = await channelMessagesCollection.watch(ids);
this.stream.onNext(this.notify);
}
}
UserObserver
export class UserObserver extends Observable {
constructor() {
super();
this.cache =
new LRU(50);
}
async sync(id);
::sync(id)
if (this.stream) {
this.stream.close();
}
if (this.cache.has(id)) {
return this.cache.get(id);
}
const user = await usersCollection.find({ _id: id }).first();
this.cache.set(id, user);
this.stream = await usersCollection.watch(this.cache.keys());
this.stream.onNext((event) => { this.notify(event) });
return user;
ChannelSubscriptionObserver
export class ChannelSubscriptionObserver extends Observable {
constructor() {
super();
}
async notify(data);
::notify
const subscription = data.fullDocument
if (data.operationType != "update"
|| subscription == null
|| subscription.localTimestamp == subscription.remoteTimestamp) {
return
}
await this.updateLocalVector(data.documentKey["_id"], subscription)
super.notify(data);
::updateLocalVector(id, sub)
const latestMessageIds = (await channelMessagesCollection.find({
channelId: subscription.channelId,
remoteTimestamp: {
$gt: subscription.localTimestamp,
$lte: subscription.remoteTimestamp
}
}).asArray()).map(it => it["_id"])
await channelMessageObserver.sync(latestMessageIds)
await channelSubscriptionsCollection.updateOne(
{ _id: documentId },
{ $set : { localTimestamp: subscription.remoteTimestamp }}
)
Functions & Triggers
exports = function(changeEvent) {
// Parse values from the insert change event
// changeEvent.operationType === "INSERT"
const insertedDoc = changeEvent.fullDocument
const { _id, name } = insertedDoc;
// Instantiate a MongoDB service client
const cluster = context.services.get("myCluster");
const myDb = cluster.db("myDb");
const myColl = myDb.collection("myColl");
myColl.updateOne({ _id }, {
"$set": { "someField": "$set" }
})
}
Invoke Serverless Functions
• Written in JavaScript (ES6+)
• Execute dynamically based on context
• Run as a specific application user
• Connect to your application components
• Callable from an SDK or another Function
Trigger Functions on Events
• React to changes in a MongoDB collection
• Execute logic when users are created or log in
• Schedule functions with CRON expressions
functions > subscribeToChannel
var mongo = context.services.get("mongodb-atlas");
var channelMembersCollection = mongo.db("chats").collection("channel_members");
var channelSubscriptionsCollection =
mongo.db("chats").collection("channel_subscriptions");
await channelMembersCollection.updateOne({ "_id" : channelId },
{ "$push": { "members" : userId },
"$set": {
"__stitch_sync_version" : {
"spv" : BSON.Int32(1), "id" : “0", "v" : BSON.Long(1) }}},
{ upsert: true });
functions > subscribeToChannel
var otherSubscription = await channelSubscriptionsCollection.findOne({
"channelId" : channelId
})
var insertOneResult = await channelSubscriptionsCollection.insertOne({
"ownerId" : userId, "deviceId": deviceId, "channelId" : channelId,
"localTimestamp" : 0,
"remoteTimestamp": otherSubscription ? otherSubscription .remoteTimestamp : 0 }
);
return insertOneResult.insertedId;
::sendMessage
async sendMessage(text) {
const msg = ChannelMessage(
new BSON.ObjectId(),
client.auth.user.id,
"default",
text,
Date.now(),
undefined);
await channelMessagesCollection.insertOne(msg);
this.state.messages.push(msg);
this.setState(this.state);
}
triggers > channelMessageHasInserted
triggers > channelMessageHasInserted
var messageId = changeEvent.documentKey._id;
var channelId = changeEvent.fullDocument.channelId;
var messagesCollection = context.services
.get("mongodb-atlas").db("chats").collection("messages");
var subscriptionsCollection = context.services
.get("mongodb-atlas")
.db("chats").collection("channel_subscriptions");
triggers > channelMessageHasInserted
await subscriptionsCollection.updateMany(
{ "channelId" : channelId },
{ "$inc": { "remoteTimestamp" : 1 }});
await messagesCollection.updateOne(
{ "_id" : messageId },
{ "$set":
{
"sentAt" : Date.now(),
"remoteTimestamp": (await subscriptionsCollection.findOne(
{ "channelId" : channelId })).remoteTimestamp
}
});
::subscribeToChannel
async subscribeToChannel() {
channelMessageObserver.subscribe(event => {
this.state.messages.push(event.fullDocument);
this.setState(this.state);
});
const subscriptionId = await client.callFunction("subscribeToChannel", [
client.auth.user.id,
new ObjectId().toHexString,
"default"
]);
channelSubscriptionObserver.sync(subscriptionId);
}
The power of observation
export default class ChatMessage extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
this.observeUser();
}
The power of observation
render() {
const direction = this.props.isFromCurrentUser ? "right" : "left";
const { isLastFromUser, isFirstFromUser, shouldShowHeader } = this.props;
const { sentAt, content } = this.props.message;
const avatar = this.state.user &&
this.state.user.avatar ? 'data:image/jpeg;base64,' +
this.state.user.avatar.buffer.toString('base64') :
this.state.user ? defaultAvatars(this.state.user.defaultAvatarOrdinal)
: "img/mind_map_icn_3.png";
return (...)
}
The power of observation
async observeUser() {
usersObserver.subscribe(event => {
if (event.operationType != "update"
|| event.documentKey["_id"] != this.props.message.ownerId) {
return;
}
this.state = { user: event.fullDocument }
this.setState(this.state);
});
this.state = { user: await usersObserver.sync(this.props.message.ownerId) }
this.setState(this.state);
}
The power of observation
<input type="file" id="file-upload" onChange={() => {
var reader = new FileReader();
reader.onload = function(e) {
const buffer = new Uint8Array(e.target.result);
console.log(buffer);
const binary = new Binary(buffer);
binary.write(buffer);
console.log(binary);
usersCollection.updateOne(
{ _id: client.auth.user.id },
{ $set: { avatar: binary }}
).then((it) => console.log(it));
}
reader.readAsArrayBuffer(document.querySelector('input').files[0]);
}}/>
Licensing,
Pricing, and
Support
What’s Next
Thank You!

More Related Content

What's hot

Dependency Injection with Unity Container
Dependency Injection with Unity ContainerDependency Injection with Unity Container
Dependency Injection with Unity ContainerMindfire Solutions
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB
 
Jasig Cas High Availability - Yale University
Jasig Cas High Availability -  Yale UniversityJasig Cas High Availability -  Yale University
Jasig Cas High Availability - Yale UniversityJasig CAS
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Patterngoodfriday
 
Techlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with VaadinTechlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with VaadinPeter Lehto
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right wayThibaud Desodt
 
ASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CSASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CStutorialsruby
 
Jug Guice Presentation
Jug Guice PresentationJug Guice Presentation
Jug Guice PresentationDmitry Buzdin
 
Entity Manager
Entity ManagerEntity Manager
Entity Managerpatinijava
 
Service Architecture patterns
Service Architecture patternsService Architecture patterns
Service Architecture patternsVivek Singh
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopPeter Lehto
 
Vaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationVaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationPeter Lehto
 
Building impressive layout systems with vaadin
Building impressive layout systems with vaadinBuilding impressive layout systems with vaadin
Building impressive layout systems with vaadinPeter Lehto
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsAleksandar Ilić
 

What's hot (17)

Dependency Injection with Unity Container
Dependency Injection with Unity ContainerDependency Injection with Unity Container
Dependency Injection with Unity Container
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDB
 
Jasig Cas High Availability - Yale University
Jasig Cas High Availability -  Yale UniversityJasig Cas High Availability -  Yale University
Jasig Cas High Availability - Yale University
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
 
Techlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with VaadinTechlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with Vaadin
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
ASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CSASPNET_MVC_Tutorial_06_CS
ASPNET_MVC_Tutorial_06_CS
 
Android+ax+app+wcf
Android+ax+app+wcfAndroid+ax+app+wcf
Android+ax+app+wcf
 
Jug Guice Presentation
Jug Guice PresentationJug Guice Presentation
Jug Guice Presentation
 
JavaCro'15 - GWT integration with Vaadin - Peter Lehto
JavaCro'15 - GWT integration with Vaadin - Peter LehtoJavaCro'15 - GWT integration with Vaadin - Peter Lehto
JavaCro'15 - GWT integration with Vaadin - Peter Lehto
 
Ejb6
Ejb6Ejb6
Ejb6
 
Entity Manager
Entity ManagerEntity Manager
Entity Manager
 
Service Architecture patterns
Service Architecture patternsService Architecture patterns
Service Architecture patterns
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - Workshop
 
Vaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationVaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfiguration
 
Building impressive layout systems with vaadin
Building impressive layout systems with vaadinBuilding impressive layout systems with vaadin
Building impressive layout systems with vaadin
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
 

Similar to MongoDB Stitch Tutorial

Scalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureScalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureFDConf
 
MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...
MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...
MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...MongoDB
 
MongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your DeviceMongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your DeviceMongoDB
 
MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...MongoDB
 
MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...MongoDB
 
MongDB Mobile: Bringing the Power of MongoDB to Your Device
MongDB Mobile: Bringing the Power of MongoDB to Your DeviceMongDB Mobile: Bringing the Power of MongoDB to Your Device
MongDB Mobile: Bringing the Power of MongoDB to Your DeviceMatt Lord
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and SymfonyIgnacio Martín
 
MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...MongoDB
 
MongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your DeviceMongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your DeviceMongoDB
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade ServerlessKatyShimizu
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade ServerlessKatyShimizu
 
MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...MongoDB
 
MongoDB.local Berlin: MongoDB Mobile
MongoDB.local Berlin: MongoDB MobileMongoDB.local Berlin: MongoDB Mobile
MongoDB.local Berlin: MongoDB MobileMongoDB
 
Integrating Force.com with Heroku
Integrating Force.com with HerokuIntegrating Force.com with Heroku
Integrating Force.com with HerokuPat Patterson
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!Sébastien Levert
 
GWT.create 2013: Introduction to GXT
GWT.create 2013: Introduction to GXTGWT.create 2013: Introduction to GXT
GWT.create 2013: Introduction to GXTniloc132
 
Java Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAXJava Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAXIMC Institute
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Luciano Mammino
 

Similar to MongoDB Stitch Tutorial (20)

Scalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureScalable Angular 2 Application Architecture
Scalable Angular 2 Application Architecture
 
MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...
MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...
MongoDB.local Seattle 2019: MongoDB Mobile: Bringing the Power of MongoDB to ...
 
MongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your DeviceMongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your Device
 
MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Sydney 2019: MongoDB Mobile: Bringing the Power of MongoDB to Y...
 
ELEVATE Paris
ELEVATE ParisELEVATE Paris
ELEVATE Paris
 
MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...
MongoDB.local Austin 2018: MongoDB Mobile: Bringing the Power of MongoDB to Y...
 
MongDB Mobile: Bringing the Power of MongoDB to Your Device
MongDB Mobile: Bringing the Power of MongoDB to Your DeviceMongDB Mobile: Bringing the Power of MongoDB to Your Device
MongDB Mobile: Bringing the Power of MongoDB to Your Device
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local Atlanta: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
 
MongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your DeviceMongoDB Mobile: Bringing the Power of MongoDB to Your Device
MongoDB Mobile: Bringing the Power of MongoDB to Your Device
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
MongoDB.local DC 2018: MongoDB Mobile: Bringing the Power of MongoDB to Your ...
 
MongoDB.local Berlin: MongoDB Mobile
MongoDB.local Berlin: MongoDB MobileMongoDB.local Berlin: MongoDB Mobile
MongoDB.local Berlin: MongoDB Mobile
 
Integrating Force.com with Heroku
Integrating Force.com with HerokuIntegrating Force.com with Heroku
Integrating Force.com with Heroku
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!
 
GWT.create 2013: Introduction to GXT
GWT.create 2013: Introduction to GXTGWT.create 2013: Introduction to GXT
GWT.create 2013: Introduction to GXT
 
Android development
Android developmentAndroid development
Android development
 
Java Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAXJava Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAX
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
 

More from MongoDB

MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB
 
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 MongoDB SoCal 2020: MongoDB Atlas Jump Start MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB SoCal 2020: MongoDB Atlas Jump StartMongoDB
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB
 

More from MongoDB (20)

MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
 
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 MongoDB SoCal 2020: MongoDB Atlas Jump Start MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
 

Recently uploaded

Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
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
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
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
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 

Recently uploaded (20)

Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
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
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
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
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 

MongoDB Stitch Tutorial

  • 1. MongoDB Stitch Tutorial Deep Dive on MongoDB Serverless
  • 2. This presentation contains “forward-looking statements” within the meaning of Section 27A of the Securities Act of 1933, as amended, and Section 21E of the Securities Exchange Act of 1934, as amended. Such forward-looking statements are subject to a number of risks, uncertainties, assumptions and other factors that could cause actual results and the timing of certain events to differ materially from future results expressed or implied by the forward-looking statements. Factors that could cause or contribute to such differences include, but are not limited to, those identified our filings with the Securities and Exchange Commission. You should not rely upon forward-looking statements as predictions of future events. Furthermore, such forward-looking statements speak only as of the date of this presentation. In particular, the development, release, and timing of any features or functionality described for MongoDB products remains at MongoDB’s sole discretion. This information is merely intended to outline our general product direction and it should not be relied on in making a purchasing decision nor is this a commitment, promise or legal obligation to deliver any material, code, or functionality. Except as required by law, we undertake no obligation to update any forward-looking statements to reflect events or circumstances after the date of such statements. Safe Harbor Statement
  • 5. Stitch: What is it? • Provide an interface for users to interact with your app. • Handle user actions and send requests to the app server. • Authenticate users and allow them to use app features. • Handle data requests and execute business logic. • Store and search persisted application data. • Manage data integrity, consistency, and availability.
  • 6. Stitch SDK Packages the entire mobile stack together Stitches the frontend and backend together • End-to-end Mobile SDK • API for local storage • API for remote Stitch service invocation • API for syncing between local and remote • Provides a transparent bridge for applications iOS SDK: https://github.com/mongodb/stitch-ios-sdk/ Android SDK: https://github.com/mongodb/stitch-android-sdk/ final StitchAppClient client = Stitch.getDefaultAppClient(); final MongoClient mongoClient = client.getServiceClient(LocalMongoDbService.ClientFactory); MongoCollection<Document> items = mongoClient.getDatabase(TodoItem.TODO_LIST_DATABASE).getCollection(TodoItem.TODO_LIST_COLLE CTION); public void updateChecked(final ObjectId itemId, final boolean isChecked) { final Document updateDoc = new Document("$set", new Document(TodoItem.CHECKED_KEY, isChecked)); if (isChecked) { updateDoc.append("$currentDate", new Document(TodoItem.DONE_DATE_KEY, true)); } else { updateDoc.append("$unset", new Document(TodoItem.DONE_DATE_KEY, "")); } items.updateOne(new Document(TodoItem.ID_KEY, itemId), updateDoc); ... } private List<TodoItem> getItems() { final ArrayList<TodoItem> todoItems = new ArrayList<>(); for (final Document doc : items.find()) { if (TodoItem.isTodoItem(doc)) { final TodoItem item = new TodoItem(doc); todoItems.add(item); } } return todoItems; } Stitch
  • 7. Let’s build a chat app
  • 8. User Authentication Built-In Identity Providers • Anonymous • Email / Password • OAuth 2.0 (Facebook & Google) • API Key (Server & User) • Custom (Bring Your Own Auth) Application Users • Associated with one or more identities • Must authenticate to send requests • Trigger authentication events
  • 9. Custom User /** * The customer user object relative to our Stitch user that contains * extended profile information. * * @param _id {String} the id of the associated Stitch user * @param name {String} the chosen username of this user * @param defaultAvatarOrdinal {Number} 0-7 the default avatar we choose for this user * @param avatar {Binary?} the uploaded avatar for this user * @param channelsSubscribedTo {StringArray} the channels this user is subscribed to */ export function User(_id, name, defaultAvatarOrdinal, avatar, channelsSubscribedTo) { return { _id, name, defaultAvatarOrdinal, avatar, channelsSubscribedTo }; }
  • 10. Server-Side Rules Declarative Expressions • Specify rule conditions with a document • Access specific request/document values. Dynamic Evaluation • Add complex and/or personalized rules with expansions and operators. Secure by Default • If an action does not pass any rule, Stitch prevents the action
  • 11. LoginView export default class LoginView extends React.Component { constructor(props) { super(props); this.state = { inputValue: '' }; } updateInputValue(evt) { this.setState({ inputValue: evt.target.value }); } render() { return ( <ChatLayout> <LinearLayout> <ChitChat>chit chat</ChitChat> <Block /> <LoginInput placeholder="username" style={{marginBottom: 20 + "px"}} value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)} /> <LoginButton onClick={async () => await this.onLogin()}>login</LoginButton> </LinearLayout> </ChatLayout> ); }
  • 12. async onLogin() { if (this.state.inputValue.length < 3) { return } const stitchUser = await client.auth.loginWithCredential(new AnonymousCredential()); await usersCollection.insertOne( EJSON.serialize(User( stitchUser.id, this.state.inputValue, Math.floor(Math.random() * Math.floor(7)), null, ["default"] ))); const rootElement = document.getElementById("root"); ReactDOM.render(<ChatRoom />, rootElement); }
  • 13. ChannelSubscription /** * A vector clock that notifies us when a new message has been sent. * * @param _id {ObjectId} the unique id of this subscription * @param ownerId {String} the user id of the owner of this subscription * @param deviceId {String} the device id of the owner of this subscription * @param localTimestamp {Numer} the local logical time * @param remoteTimestamp {Number} the remote logical time */ export function ChannelSubscription(_id, channelId, ownerId, subscriptionId, localTimestamp, remoteTimestamp) { return { _id, channelId, ownerId, deviceId: subscriptionId, localTimestamp, remoteTimestamp }; }
  • 14. ChannelMessage /** * A message one would send to a channel. * * @param _id {ObjectId} the unique id of the message * @param channelId {String} the id of the channel this was sent to * @param content {String} the actual text of the message * @param sentAt {Number} the time the message was sent to the server or the time the message hit the server * @param remoteTimestamp {Number} the logical time of the message (to be updated by the server trigger) */ export function ChannelMessage(_id, ownerId, channelId, content, sentAt, remoteTimestamp) { return { _id, ownerId, channelId, content, sentAt, remoteTimestamp }; }
  • 15. ChatRoom export default class ChatRoom extends React.Component { constructor(props) { super(props); this.state = { isLoading: false, messages: [], messageText: "" } } componentDidMount() { this.subscribeToChannel(); } render() { return <ChatLayout> <ChatFeed messages={this.state.messages} /> <ChatBar sendMessage={text => this.sendMessage(text)} setMessageText={(txt) => { this.state.messageText = txt this.setState(this.state) }} messageText={this.state.messageText} /> </ChatLayout>; } }
  • 16. ChannelMessageObserver export class ChannelMessageObserver extends Observable { async sync(ids) { if (this.stream) { this.stream.close(); } (await channelMessagesCollection.find({_id: { $in: ids }}).asArray()).forEach((msg) => { this.notify({fullDocument: msg, operationType: "insert"}) }); this.stream = await channelMessagesCollection.watch(ids); this.stream.onNext(this.notify); } }
  • 17. UserObserver export class UserObserver extends Observable { constructor() { super(); this.cache = new LRU(50); } async sync(id);
  • 18. ::sync(id) if (this.stream) { this.stream.close(); } if (this.cache.has(id)) { return this.cache.get(id); } const user = await usersCollection.find({ _id: id }).first(); this.cache.set(id, user); this.stream = await usersCollection.watch(this.cache.keys()); this.stream.onNext((event) => { this.notify(event) }); return user;
  • 19. ChannelSubscriptionObserver export class ChannelSubscriptionObserver extends Observable { constructor() { super(); } async notify(data);
  • 20. ::notify const subscription = data.fullDocument if (data.operationType != "update" || subscription == null || subscription.localTimestamp == subscription.remoteTimestamp) { return } await this.updateLocalVector(data.documentKey["_id"], subscription) super.notify(data);
  • 21. ::updateLocalVector(id, sub) const latestMessageIds = (await channelMessagesCollection.find({ channelId: subscription.channelId, remoteTimestamp: { $gt: subscription.localTimestamp, $lte: subscription.remoteTimestamp } }).asArray()).map(it => it["_id"]) await channelMessageObserver.sync(latestMessageIds) await channelSubscriptionsCollection.updateOne( { _id: documentId }, { $set : { localTimestamp: subscription.remoteTimestamp }} )
  • 22. Functions & Triggers exports = function(changeEvent) { // Parse values from the insert change event // changeEvent.operationType === "INSERT" const insertedDoc = changeEvent.fullDocument const { _id, name } = insertedDoc; // Instantiate a MongoDB service client const cluster = context.services.get("myCluster"); const myDb = cluster.db("myDb"); const myColl = myDb.collection("myColl"); myColl.updateOne({ _id }, { "$set": { "someField": "$set" } }) } Invoke Serverless Functions • Written in JavaScript (ES6+) • Execute dynamically based on context • Run as a specific application user • Connect to your application components • Callable from an SDK or another Function Trigger Functions on Events • React to changes in a MongoDB collection • Execute logic when users are created or log in • Schedule functions with CRON expressions
  • 23. functions > subscribeToChannel var mongo = context.services.get("mongodb-atlas"); var channelMembersCollection = mongo.db("chats").collection("channel_members"); var channelSubscriptionsCollection = mongo.db("chats").collection("channel_subscriptions"); await channelMembersCollection.updateOne({ "_id" : channelId }, { "$push": { "members" : userId }, "$set": { "__stitch_sync_version" : { "spv" : BSON.Int32(1), "id" : “0", "v" : BSON.Long(1) }}}, { upsert: true });
  • 24. functions > subscribeToChannel var otherSubscription = await channelSubscriptionsCollection.findOne({ "channelId" : channelId }) var insertOneResult = await channelSubscriptionsCollection.insertOne({ "ownerId" : userId, "deviceId": deviceId, "channelId" : channelId, "localTimestamp" : 0, "remoteTimestamp": otherSubscription ? otherSubscription .remoteTimestamp : 0 } ); return insertOneResult.insertedId;
  • 25. ::sendMessage async sendMessage(text) { const msg = ChannelMessage( new BSON.ObjectId(), client.auth.user.id, "default", text, Date.now(), undefined); await channelMessagesCollection.insertOne(msg); this.state.messages.push(msg); this.setState(this.state); }
  • 27. triggers > channelMessageHasInserted var messageId = changeEvent.documentKey._id; var channelId = changeEvent.fullDocument.channelId; var messagesCollection = context.services .get("mongodb-atlas").db("chats").collection("messages"); var subscriptionsCollection = context.services .get("mongodb-atlas") .db("chats").collection("channel_subscriptions");
  • 28. triggers > channelMessageHasInserted await subscriptionsCollection.updateMany( { "channelId" : channelId }, { "$inc": { "remoteTimestamp" : 1 }}); await messagesCollection.updateOne( { "_id" : messageId }, { "$set": { "sentAt" : Date.now(), "remoteTimestamp": (await subscriptionsCollection.findOne( { "channelId" : channelId })).remoteTimestamp } });
  • 29. ::subscribeToChannel async subscribeToChannel() { channelMessageObserver.subscribe(event => { this.state.messages.push(event.fullDocument); this.setState(this.state); }); const subscriptionId = await client.callFunction("subscribeToChannel", [ client.auth.user.id, new ObjectId().toHexString, "default" ]); channelSubscriptionObserver.sync(subscriptionId); }
  • 30. The power of observation export default class ChatMessage extends React.Component { constructor(props) { super(props); this.state = {}; } componentDidMount() { this.observeUser(); }
  • 31. The power of observation render() { const direction = this.props.isFromCurrentUser ? "right" : "left"; const { isLastFromUser, isFirstFromUser, shouldShowHeader } = this.props; const { sentAt, content } = this.props.message; const avatar = this.state.user && this.state.user.avatar ? 'data:image/jpeg;base64,' + this.state.user.avatar.buffer.toString('base64') : this.state.user ? defaultAvatars(this.state.user.defaultAvatarOrdinal) : "img/mind_map_icn_3.png"; return (...) }
  • 32. The power of observation async observeUser() { usersObserver.subscribe(event => { if (event.operationType != "update" || event.documentKey["_id"] != this.props.message.ownerId) { return; } this.state = { user: event.fullDocument } this.setState(this.state); }); this.state = { user: await usersObserver.sync(this.props.message.ownerId) } this.setState(this.state); }
  • 33. The power of observation <input type="file" id="file-upload" onChange={() => { var reader = new FileReader(); reader.onload = function(e) { const buffer = new Uint8Array(e.target.result); console.log(buffer); const binary = new Binary(buffer); binary.write(buffer); console.log(binary); usersCollection.updateOne( { _id: client.auth.user.id }, { $set: { avatar: binary }} ).then((it) => console.log(it)); } reader.readAsArrayBuffer(document.querySelector('input').files[0]); }}/>