Colm Troy
Colm Troy

Reputation: 1947

Querying nested embedded documents with mongoid (or alternative)

I currently store a series of tweets as documents in mongodb the schema of which directly map to the json returned by the streaming API.

The schema is very verbose with many nested embedded documents e.g.

{
  "_id": ObjectId("4f547c17e948fb6e2e00197d"),
  "key: value",
  "...",
  "...",
  "entities": {
    "urls": [
       {
        "indices": [
          58,
          78
        ],
        "display_url": "bit.ly\/yJwQsm",
        "url": "http:\/\/t.co\/x5ccL6So",
        "expanded_url": "http:\/\/bit.ly\/yJwQsm"
      }
    ],
  }
  "other parent key pair values here" 
}

Sometimes the urls embed will be empty while other times it will contain more than one value (in a further array like nesting [0], [1] [n])

I'd like to extract the link values from this json document.

I have a simple Sinatra app where I've defined a Tweets model and using mongoid's dynamic attributes I'm able to quickly output values from the document as follows:

<% @tweets.each do |tweet| %>
<li><%= tweet._id %></li>
<li><%= tweet.user.screen_name %></li>
<li><%= tweet.entities %></li>

When I try to output a value like

<li><%= tweet.entities.urls %></li>

I start to see errors where the method does not exist. The "tweet.entities" call on it's own will return the contents of the nested embed. Does anyone have any ideas as to how I can check for the existence of the child embed so I can then traverse down into it? Is what I'm trying to do even possible with mongoid? My query at the moment just returns the full document.

Upvotes: 1

Views: 654

Answers (1)

shingara
shingara

Reputation: 46914

The best in your case is override the entites method to return an empty Entity model if there are no entities key. Or you can create a new methode entities_url doing the job of check ifg there are url and or and return value if there are url

class Tweet

  def entities
    super || Entity.new
  end

  def entities_url
    entities.respond_to?(:url) ? entities.url : ''
  end

end

Upvotes: 1

Related Questions