Using MongoDb in Phoenix framework

Hi is there any way to connect mongodb with Ecto with latest version? I really need mongodb as a datastore. thanks in advance
I have gone through couple but this is not working well with latest release

  1. https://github.com/michalmuskala/mongodb_ecto

  2. https://github.com/ericmj/mongodb

if anyone is using mongo in production with phoenix please share your experience
Thanks in Advance

1 Like

Putting aside my whole dislike towards MongoDB (caused by unfortunate experience of using it’s earl-ish versions), I do not think you can get to work MongoDB as a back-end for Ecto 2.0 just yet. The work is still work in progress, and looks like the guy over here still hasn’t given up hope on making it work with each other: https://github.com/michalmuskala/mongodb_ecto/pull/91

Having said that, there’s nothing from stopping you from using mongo driver directly (2nd link). It’s nice enough I think.

3 Likes

thanks for quick reply looking forward to it. I would love to use postgres but the usecase suits to use mongodb for us. anyway thanks

I really doubt that this is true. Postgres can be configured to be very elastic and probably replace all cases where MongoDB can be used - with better result - with exception to keeping open cursors.

It may be as well that you do not need any of the above. You are in Erlang ecosystem in the end. Maybe you should consider some persistence solution like DETS if your data / use case allows that. But I can’t say more since I don’t know our use case :slight_smile:

2 Likes

Thanks, I am pretty new to postgres coming from meteor background. was using mongo alot but just found postgress can store jsonp data. i think i will stick with postgress now. thanks

1 Like

yes, it can, and if you go with UUID for IDs and JSONB as datatype you get more or less the same “feel” as with Mongo with full support from Phoenix. JSONB field just becomes Map in Elixir.

1 Like

@hubertlepicki Do you happen to know of any good examples of using JSONB?

I’m trying to migrate a Meteor application to phoenix, but there are a couple of areas that use custom fields and I’m struggling to find examples on how to handle them.

So far I have this:

embeds_many :style, App.CustomField

and then

defmodule App.CustomField do 
    embedded_schema do
      field :data, {:array, :map}
    end
end

This saves the JSONB correctly, but I’m not sure how to display it in my eex templates? Do I need to use Poison?

I am sorry, I don’t know. I only used it with :map data type. I do not try to use too many ORM features as my relationship with those libs generally “is complicated”.

When you use :map it uses Elixir’s maps that are pretty natural translation from one to another.

1 Like

Ecto translates between jsonb and elixir maps so you will be working with normal elixir maps in your templates.

2 Likes

@ericmj @hubertlepicki thanks for replying guys.

I think my data is either in the wrong format or I’m missing something.

Does the result below look correct? if so, how do I access “color”?

[%Ap.Block{__meta__: #Ecto.Schema.Metadata<:loaded, "blocks">, 
  id: 1, 
  name: "foo",
  style: [%Ap.CustomField{
    data: [%{"color" => "red"}],
    id: "4222329c-cac4-4e1d-bfa6-6c440dcb7b59"}
  ], 
  template: "baz",
  inserted_at: #Ecto.DateTime<2016-11-18 00:58:41>,
  updated_at: #Ecto.DateTime<2016-11-18 00:58:41>}]

That does look correct. These are normal elixir values so you can access color by hd(hd(block.style).data)["color"].

Thank you! that worked perfectly.

Looks like I need to read up on lists as I wasn’t aware of hd()

hd/1 and tl/1 are from erlang, and thus in the Elixir Kernel module. :slight_smile:

2 Likes

Sorry so keep bringing this up, but I’m still not sure I’m using this correctly.

I have an application with 20+ templates called blocks which can all potentially have different styles. They all share a “Block” schema but need a flexible way to add different styles which is why I thought jsonb would be the way to go.

[%Ap.Block{__meta__: #Ecto.Schema.Metadata<:loaded, "blocks">, 
  id: 1, 
  name: "foo",
  style: [%Ap.CustomField{
    data: [
      %{"color" => "red"},
      %{"h2" => "#303030"},
      %{"background-image" => "image.jpg"}
    ],
    id: "4222329c-cac4-4e1d-bfa6-6c440dcb7b59"}
  ], 
  template: "baz",
  inserted_at: #Ecto.DateTime<2016-11-18 00:58:41>,
  updated_at: #Ecto.DateTime<2016-11-18 00:58:41>}]

Basically, I want my final template to look something like the pseudo code below but I’m still not sure the best way to save the data and then how to easily access it later?

<style scoped>
  p {
    color: <%= style.data.color %>
  }
  h2 {
    color: <%= style.data.h2 %>
  }
</style>

<section style="background-image: <%= style.data.background-image %>">
  <h2>My Heading</h2>
  <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.</p>
</section>