256dpi / lungo

A MongoDB compatible embeddable database and toolkit for Go.
MIT License
462 stars 15 forks source link

Node.js? #10

Open xet7 opened 3 years ago

xet7 commented 3 years ago

Hi, can this be used with Node.js MongoDB driver? Like with www.meteor.com ?

256dpi commented 3 years ago

No, it is Go only ATM. However, if one would add a TCP frontend implementing the MongoDB wire protocol, it could be done.

xet7 commented 3 years ago

@256dpi

Is there any TCP MongoDB wire protocol implementation in Go yet anywhere?

xet7 commented 3 years ago

And how hard it would be to implement it?

xet7 commented 3 years ago

I'm asking, because for Raspberry Pi, MongoDB uses a lot of RAM and CPU. For 32bit, MongoDB database size is very limited, and only 64bit has full features. MongoDB also is not available for some CPU architectures.

For Java, there is ToroDB that has MongoDB wire protocol implemented, but it uses a lot of RAM, and it's not yet possible to use ToroDB+PostgreSQL without MongoDB installation completely.

256dpi commented 3 years ago

Not that I'm aware of. I played with that idea some months ago and it actually looked quite straightforward, since the wire protocol is just BSON documents sent back and forth AFAIK. My motivation was to be able to explore a lungo DB using existing MongoDB GUI apps.

xet7 commented 3 years ago

@256dpi

Do you have time to sometime look at it a little, and add some notes as comment to this issue about what already exists, what is missing, and what would be possible next steps for some other contributor trying to help with implementing it?

xet7 commented 3 years ago

@256dpi

Can you give some links to parts of your code, MongoDB wire protocol docs, etc that you did previously look at?

256dpi commented 3 years ago

The protocol itself is documented here: https://docs.mongodb.com/manual/reference/mongodb-wire-protocol.

It would be nice to have a lungo/wirekit package that implements the wire protocol and and a generic interface to handle the commands. This is would also allow others to expose things over the MongoDB wire protocol too. In the main lungo package we would then proccess those commands using the already available API exposed by the lungo.Engine.

For the wirekit I have something like this in mind:

package wirekit

import (
    "context"
    "net"

    "go.mongodb.org/mongo-driver/bson"
)

type Header struct {
    // ...
}

type Query struct {
    Header               Header `bson:"header"`
    Flags                int32  `bson:"flags"`
    FullCollectionName   string `bson:"fullCollectionName"`
    NumberToSkip         int32  `bson:"numberToSkip"`
    NumberToReturn       int32  `bson:"numberToReturn"`
    Query                bson.D `bson:"query"`
    ReturnFieldsSelector bson.D `bson:"returnFieldsSelector"`
}

type Update struct {
    // ...
}

type Reply struct {
    // ...
}

type Handler interface {
    Query(*Query) (*Reply, error)
    Update(*Update) error
    // ...
}

func Serve(conn net.Conn, h Handler) error {
    // handle connection using the provided handler...
}

I'm happy to support you if want to start working on implementing this.

dsikes commented 2 years ago

Perhaps something along these lines could be useful? https://github.com/mongodb/mongonet

I am also interested in having a "lightweight" mongodb compatible server written in Golang.

Let me know how I can help.

zenhack commented 2 years ago

I'm tempted to take a whack at this (I futzed around with the low-level serialization the other night). Based on the doc @256dpi linked, the wire protocol does look pretty straightforward, though as of mongo 5.x it looks like basically everything has been folded into OP_MSG, and I don't see anything there that describes the semantics of messages within that.

xet7 commented 2 years ago

@zenhack

Yes, it would benefit many, lungo would use much less resources than MongoDB.

256dpi commented 2 years ago

I did some experiments on this a while ago here: https://github.com/256dpi/lungo/tree/wirekit. Following the MongoDB 5.x deprecations, we could cleanup a lot, since only support for OP_MSG is needed, as @zenhack suggested. More work is needed to implement a basic set of commands and test compatibility with existing MongoDB tools. But getting the pipes done is a good first step!

AlekSi commented 1 year ago

There is also a FerretDB that could be embedded into Go programs. Currently, it depends on PostgreSQL for storing data, but we are also working on the SQLite backend.

(I'm the co-founder and CTO for FerretDB)

shehackedyou commented 8 months ago

There is also the mongo proxy that can setup a server to receive the commands and feed them into whichever mongoDB compatible database, or if you have the time, you could stick it into any database.