Search code examples
javamongodbfreemarkermongodb-java

mongodb Queries: How to get nested Data on a Spark/Freemarker page?


This may be a bit more complicated than it needs to be, but I am using:

  • mongoDB
  • Spark
  • Freemarker
  • java

I cannot figure out how to access embedded data in mongodb to print on the website. I want to be able to look through the records, find which interface has a "label" with the value "MGMT" and then print the info for that interface. The problem is, I embed them in a "networking" collection. How do I access that info?

Important lines of Code:

java:

try {
                        Template helloTemplate = configuration.getTemplate("hello.ftl");

                        DBObject document = collection.findOne();



                        helloTemplate.process(document, writer);

                        System.out.println(writer);
                    } catch (Exception e) {
                        halt(500);
                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }

Full Code:

.java:

import com.mongodb.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import spark.Request;
import spark.Response;
import spark.Route;
import spark.Spark;

import java.io.StringWriter;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: sysrjt1
 * Date: 6/13/13
 * Time: 1:09 PM
 * To change this template use File | Settings | File Templates.
 */
public class HelloWorldMongoDBSparkFreemarkerSyle {
    public static void main(String[] args) {
        final Configuration configuration = new Configuration();
        configuration.setClassForTemplateLoading(HelloWorldMongoDBSparkFreemarkerSyle.class, "/");

        MongoClient client = null;
        try {
            client = new MongoClient(new ServerAddress("localhost", 27017 ));
        } catch (UnknownHostException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        DB database = client.getDB("systems");
        final DBCollection collection;
        collection = database.getCollection("systems");

        Spark.get(new Route("/") {
            @Override
            public Object handle(Request request, Response response) {
                StringWriter writer = new StringWriter();
                try {
                    Template helloTemplate = configuration.getTemplate("hello.ftl");

                    DBObject document = collection.findOne();



                    helloTemplate.process(document, writer);

                    System.out.println(writer);
                } catch (Exception e) {
                    halt(500);
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
                return writer;
            }
        });
    }
}

my HTML template (hello.ftl):

<!DOCTYPE html>
<html>
<head>
    <title>Welcome!</title>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Management IP</th>
                <th>RAM</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>${name}</td>
                <td>${ipAddr}</td> <! -- this line fails -->
                <td>${ram}</td>
            </tr>
        </tbody>
    </table>

     <h1>Server Name: ${name}</h1>
</body>
</html>

from mongodb:

> db.systems.findOne()
{
        "_id" : ObjectId("51b9dde5d05f675ad37ac990"),
        "name" : "abcdev01",
        "networking" : {
                "interface1" : {
                        "name" : "eth0",
                        "ipAddr" : "12.34.45.56",
                        "sNet" : "255.255.255.0",
                        "label" : "MGMT"
                },
                "interface2" : {
                        "name" : "eth1",
                        "ipAddr" : "1.2.3.4"
                }
        },
        "ram" : 102390
}

Solution

  • I guess (without knowing MongoDB) that the failing line should be something like ${networking.interface1.ipAddr}. But probably you want to list all the interfaces. Then maybe you could do:

    <#list networing.keySet() as ifname>
      ...
      ${networking[ifname].ipAddr}
      ...
    </#list>
    

    Although, if you only want to print the information about the interface with a given name, you should issue the proper query with the MongoDB API, and only pass that single interface object to FreeMarker.