diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/Catalog.java b/src/main/java/org/eclipsefoundation/marketplace/dto/Catalog.java
index dec87b555d99f2f6bdeaf2f7d648213ee3f34e2f..879be3fb2d872b22a2db5b2005b8d9b94487dabd 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/Catalog.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/Catalog.java
@@ -25,6 +25,10 @@ public class Catalog extends NodeBase {
 	private String description;
 	private String dependenciesRepository;
 	private List<Tab> tabs;
+	
+	public Catalog() {
+		this.tabs = new ArrayList<>();
+	}
 
 	/**
 	 * @return the selfContained
@@ -110,6 +114,11 @@ public class Catalog extends NodeBase {
 		this.tabs = new ArrayList<>(tabs);
 	}
 
+	@Override
+	public boolean validate() {
+		return super.validate() && tabs != null && !tabs.isEmpty();
+	}
+
 	@Override
 	public int hashCode() {
 		final int prime = 31;
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/Install.java b/src/main/java/org/eclipsefoundation/marketplace/dto/Install.java
index 8a914f9d37d430dd4be80bc5bad831f43229057b..8085ca6b7fb491e1ef2ef8aad34a94d2f8fb869e 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/Install.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/Install.java
@@ -23,7 +23,7 @@ public class Install {
 	private String javaVersion;
 	private String eclipseVersion;
 	private String locale;
-	
+
 	/**
 	 * @return the id
 	 */
@@ -136,6 +136,11 @@ public class Install {
 		this.locale = locale;
 	}
 
+	public boolean validate() {
+		return version != null && listingId != null && os != null && eclipseVersion.isEmpty() && javaVersion != null
+				&& installDate != null;
+	}
+
 	@Override
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/Listing.java b/src/main/java/org/eclipsefoundation/marketplace/dto/Listing.java
index d52eb5dade2672742918c458b621d5b0dc49e448..a6c93d3badc9da38f09e263ccfc937a236bd16f9 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/Listing.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/Listing.java
@@ -278,7 +278,6 @@ public class Listing extends NodeBase {
 		this.categoryIds = new ArrayList<>(categoryIds);
 	}
 
-
 	/**
 	 * @return the categoryIds
 	 */
@@ -382,6 +381,12 @@ public class Listing extends NodeBase {
 		this.versions = new ArrayList<>(versions);
 	}
 
+	@Override
+	public boolean validate() {
+		return super.validate() && license != null && !authors.isEmpty() && !categoryIds.isEmpty()
+				&& !versions.isEmpty();
+	}
+
 	@Override
 	public int hashCode() {
 		final int prime = 31;
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/ListingVersion.java b/src/main/java/org/eclipsefoundation/marketplace/dto/ListingVersion.java
index 24d06c97297de748e0c83bcb6c363776084940f8..6f900526d96f21d44cbb4e29c6e5fc929ca837e9 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/ListingVersion.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/ListingVersion.java
@@ -10,6 +10,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
+import org.apache.commons.lang3.StringUtils;
+
 /**
  * Domain object representing a marketplace listing version
  * 
@@ -25,7 +27,7 @@ public class ListingVersion {
 	private String minJavaVersion;
 	private String updateSiteUrl;
 	private List<FeatureId> featureIds;
-	
+
 	public ListingVersion() {
 		this.eclipseVersions = new ArrayList<>();
 		this.platforms = new ArrayList<>();
@@ -147,4 +149,9 @@ public class ListingVersion {
 		this.featureIds = new ArrayList<>(featureIds);
 	}
 
+	public boolean validate() {
+		return version != null && listingId != null && StringUtils.isAnyBlank(minJavaVersion) && platforms.isEmpty()
+				&& !eclipseVersions.isEmpty();
+	}
+
 }
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/Market.java b/src/main/java/org/eclipsefoundation/marketplace/dto/Market.java
index 911c0506ea9726bb8d94340624b5a73ef39f7438..d28bf757aea8fbad03d5ff53e316fc29488d2752 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/Market.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/Market.java
@@ -26,17 +26,32 @@ import io.quarkus.runtime.annotations.RegisterForReflection;
  */
 @RegisterForReflection
 public class Market extends NodeBase {
+	private List<String> listingIds;
 	private List<Category> categories;
 
-
 	/**
 	 * Default constructor. Creates an empty linkedlist for categories, as its
 	 * unknown how many categories the market will reference.
 	 */
 	public Market() {
+		this.listingIds = new LinkedList<>();
 		this.categories = new LinkedList<>();
 	}
 
+	/**
+	 * @return the listingIds
+	 */
+	public List<String> getListingIds() {
+		return new ArrayList<>(listingIds);
+	}
+
+	/**
+	 * @param listingIds the listingIds to set
+	 */
+	public void setListingIds(List<String> listingIds) {
+		this.listingIds = new ArrayList<>(listingIds);
+	}
+
 	/**
 	 * @return the categories
 	 */
@@ -56,7 +71,7 @@ public class Market extends NodeBase {
 	public int hashCode() {
 		final int prime = 31;
 		int result = super.hashCode();
-		result = prime * result + Objects.hash(categories);
+		result = prime * result + Objects.hash(categories, listingIds);
 		return result;
 	}
 
@@ -72,6 +87,6 @@ public class Market extends NodeBase {
 			return false;
 		}
 		Market other = (Market) obj;
-		return Objects.equals(categories, other.categories);
+		return Objects.equals(categories, other.categories) && Objects.equals(listingIds, other.listingIds);
 	}
 }
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/NodeBase.java b/src/main/java/org/eclipsefoundation/marketplace/dto/NodeBase.java
index 3035305471ad5d20027282dec8269f79bd256c39..f6f6bf6772781e515aaee31b788fbe5ca8c6703d 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/NodeBase.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/NodeBase.java
@@ -8,12 +8,14 @@ package org.eclipsefoundation.marketplace.dto;
 
 import java.util.Objects;
 
+import org.apache.commons.lang3.StringUtils;
+
 /**
  * Contains the basic fields for a node within Mongo
  * 
  * @author Martin Lowe
  */
-public class NodeBase {
+public abstract class NodeBase {
 	private String id;
 	private String title;
 	private String url;
@@ -60,6 +62,15 @@ public class NodeBase {
 		this.url = url;
 	}
 
+	/**
+	 * Call to check whether the current node is valid.
+	 * 
+	 * @return whether the current node is valid.
+	 */
+	public boolean validate() {
+		return StringUtils.isAnyEmpty(title, url);
+	}
+
 	@Override
 	public int hashCode() {
 		return Objects.hash(id, title, url);
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/MarketCodec.java b/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/MarketCodec.java
index 3a108d0c0f66685beb49a2984d922cd0c8255b0a..95414a779020e4f077647e9d1f34436fda3e1237 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/MarketCodec.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/MarketCodec.java
@@ -52,6 +52,7 @@ public class MarketCodec implements CollectibleCodec<Market> {
 		doc.put(DatabaseFieldNames.DOCID, value.getId());
 		doc.put(DatabaseFieldNames.URL, value.getUrl());
 		doc.put(DatabaseFieldNames.TITLE, value.getTitle());
+		doc.put(DatabaseFieldNames.LISTING_IDS, value.getListingIds());
 
 		documentCodec.encode(writer, doc, encoderContext);
 	}
@@ -69,6 +70,7 @@ public class MarketCodec implements CollectibleCodec<Market> {
 		out.setId(document.getString(DatabaseFieldNames.DOCID));
 		out.setUrl(document.getString(DatabaseFieldNames.URL));
 		out.setTitle(document.getString(DatabaseFieldNames.TITLE));
+		out.setListingIds(document.getList(DatabaseFieldNames.LISTING_IDS, String.class));
 		out.setCategories(document.getList(DatabaseFieldNames.LISTING_CATEGORIES, Document.class).stream()
 				.map(categoryConverter::convert).collect(Collectors.toList()));
 		
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/InstallFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/InstallFilter.java
index 29d1e8374bb39fce19f2e2ca169f22d39c94df07..e7c1e9954e439120f3f9405f3a688d45e9118160 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/InstallFilter.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/InstallFilter.java
@@ -39,7 +39,7 @@ public class InstallFilter implements DtoFilter<Install> {
 			// ID check
 			Optional<String> id = wrap.getFirstParam(UrlParameterNames.ID);
 			if (id.isPresent()) {
-				filters.add(Filters.eq(DatabaseFieldNames.DOCID, id.get()));
+				filters.add(Filters.eq(DatabaseFieldNames.LISTING_ID, id.get()));
 			}
 		}
 		// version check
diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java
index 2906257162df2b3e0cb88869933ad1f2cff62fe4..664333f0dd70f7c7fac09f7fad41507b1ed15461 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/MarketFilter.java
@@ -61,13 +61,13 @@ public class MarketFilter implements DtoFilter<Market> {
 		List<Bson> pipeline = new ArrayList<>();
 		// match the listings on the given market_id
 		pipeline.add(
-				Aggregates.match(expr(eq("$in", Arrays.asList("$$market_id", "$" + DatabaseFieldNames.MARKET_IDS)))));
+				Aggregates.match(expr(eq("$in", Arrays.asList("$" + DatabaseFieldNames.DOCID, "$$listing_ids")))));
 		// suppress all fields except category_ids
 		pipeline.add(Aggregates.project(
 				Projections.fields(Projections.excludeId(), Projections.include(DatabaseFieldNames.CATEGORY_IDS))));
 
 		// set up a var reference for the _id
-		Variable<String> id = new Variable<>("market_id", "$" + DatabaseFieldNames.DOCID);
+		Variable<String> id = new Variable<>("listing_ids", "$listing_ids");
 		// lookup all category IDS from listings with the given market ID
 		aggs.add(Aggregates.lookup(DtoTableNames.LISTING.getTableName(), Arrays.asList(id), pipeline, tempFieldName));
 		// explode all category IDS for collection
diff --git a/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java b/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java
index c27f12756193b8ab8a37a0fc72fb7f199e3298ec..f3d5f575d09a909a509a13979c8389951f126c53 100644
--- a/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java
+++ b/src/main/java/org/eclipsefoundation/marketplace/namespace/DatabaseFieldNames.java
@@ -86,6 +86,7 @@ public final class DatabaseFieldNames {
 	// install metric fields
 	public static final String METRIC_PERIODS = "periods";
 	public static final String MONTH_OFFSET_PREFIX = "offset_";
+	public static final String LISTING_IDS = "listing_ids";
 	
 	private DatabaseFieldNames() {
 	}
diff --git a/src/main/node/index.js b/src/main/node/index.js
index 58b46c0b420a47dadefca838a274e54dd0eff7e2..201316f141414f74fdb708fba947dbec17717244 100644
--- a/src/main/node/index.js
+++ b/src/main/node/index.js
@@ -38,12 +38,14 @@ for (var i=0;i<200;i++) {
 }
 const marketIds = [];
 for (var i=0;i<5;i++) {
-  marketIds.push(uuid.v4());
+  marketIds.push({uuid: uuid.v4(), listings:[]});
 }
 
-createListing(0);
-createCategory(0);
-createMarket(0);
+run();
+
+async function run() {
+  var a = await createListing(0);
+}
 
 function shuff(arr) {
   var out = Array.from(arr);
@@ -69,13 +71,14 @@ function splice(arr) {
 
 async function createListing(count) {
   if (count >= max) {
+    createCategory(0);
     return;
   }
   
   console.log(`Generating listing ${count} of ${max}`);
   var json = generateJSON(uuid.v4());
   instance.put(argv.s+"/listings/", json)
-    .then(listingCallback(json, count))
+    .then(await listingCallback(json, count))
     .catch(err => console.log(err));
 }
 
@@ -96,6 +99,7 @@ async function listingCallback(json, count) {
 
 function createCategory(count) {
   if (count >= categoryIds.length) {
+    createMarket(0);
     return;
   }
 
@@ -135,6 +139,16 @@ async function createVersion(curr, max, id) {
 }
 
 function generateJSON(id) {
+  var markets = splice(marketIds).splice(0,Math.ceil(Math.random()*2));
+  for (var marketIdx in markets) {
+    var currUuid = markets[marketIdx].uuid;
+    for (var actualMarketIdx in marketIds) {
+      if (marketIds[actualMarketIdx].uuid === currUuid) {
+        marketIds[actualMarketIdx].listings.push(id);
+        break;
+      }
+    }
+  }
   return {
     "id": id,
   	"title": "Sample",
@@ -164,7 +178,6 @@ function generateJSON(id) {
   			"url": ""
   		}
   	],
-	"market_ids": splice(marketIds).splice(0,Math.ceil(Math.random()*2)),
   "category_ids": splice(categoryIds).splice(0,Math.ceil(Math.random()*5)+1),
 	"screenshots": ["http://www.example.com/img/sample.png"]
   };
@@ -178,11 +191,12 @@ function generateCategoryJSON(id) {
   };
 }
 
-function generateMarketJSON(id) {
+function generateMarketJSON(market) {
   return {
-    "id": id,
+    "id": market.uuid,
     "title": randomWords({exactly:1, wordsPerString:Math.ceil(Math.random()*4)})[0],
-    "url": "https://www.eclipse.org"
+    "url": "https://www.eclipse.org",
+    "listing_ids": market.listings
   };
 }