title: $lookup search Mongodb
body: <h2>Objective</h2>
  
  <p>To have an efficient search using references in MongoDB. </p>
  
  <h2>Background</h2>
  
  <p>I have a Smoothie DB on Mongo. A smoothie is an object with a reference to a Food object and it is represented like:</p>
  
  <pre><code>{
      name: "Red Velvet Cake",
      ingredients: [{
          food_id: "strawberry_raw",
          //other really cool fields
      },
      //other ingredients
      ],
      preparation: "Mix everything and have fun!",
      Source: "Super Smoothies, p. 142"
  }
  </code></pre>
  
  <p>Now, a Food object is represented by the following example:</p>
  
  <pre><code>{
      "_id": "strawberry_raw",
      "name": "strawberries",
      //other really cool fields
  }
  </code></pre>
  
  <h2>Problem</h2>
  
  <p>With these schemas in mind, I am making sure that a Smoothie object knows all the Food objects that build it. Since each Smoothie object will have at most 6 or 7 food objects, I believe this is the best choice as it follows the <a href="https://www.youtube.com/watch?v=vkaRuEUtTEw" rel="nofollow noreferrer">MongoDB's Principle of least Cardinality</a>.</p>
  
  <p>However, now I want to allow the following functionalities:</p>
  
  <ol>
  <li>Given a list of ingredient names, return all smoothies that contain at least one of those ingredients</li>
  <li>Given a list of ingredient names, return only the smoothies that contain <strong>all</strong> those ingredients. </li>
  </ol>
  
  <p>And I have no idea how to do it with MongdoDB.</p>
  
  <h2>Example</h2>
  
  <p>The following examples illustrate what I want. </p>
  
  <p>Imagine I have the following Foods:</p>
  
  <pre><code>let foods = [{
          "_id": "strawberry_raw",
          "name": "strawberries"
      }, {
          "_id": "honeydew_melon_raw",
          "name": "honeydew melon"
      }, {
          "_id": "coconut_milk",
          "name": "homemade coconut milk"
      }];
  </code></pre>
  
  <p>And the following Smoothies:</p>
  
  <pre><code>let smoothies = [
  {
      name: "Coco Berry",
      ingredients: [
          { food_id: "strawberry_raw" }, 
          { food_id: "coconut_milk"}
      ],
      preparation: "Mix everything and have fun!",
      Source: "Super Smoothies, p. 142"
  }, 
  {
      name: "Tropical Melon",
      ingredients: [
          { food_id: "honeydew_melon_raw"},
          { food_id: "coconut_milk"}
      ],
      preparation: "Mix everything and have fun!",
      Source: "Super Smoothies, p. 51"
  }];
  </code></pre>
  
  <p>Given a search with the term "coconuts, strawberry", the functionalities would return:</p>
  
  <ol>
  <li>Coco Berry and Tropical Melon, as both smoothie have at least one of the ingredients (coconut milk)</li>
  <li>Coco Berry, as this smoothie has both ingredients, and the second one is missing one ingredient. </li>
  </ol>
  
  <h2>What I tried and what i need</h2>
  
  <p>I know that to turn a search like "coconuts" return a Food with name "Coconut Milk" I have to index the names in the Food collection, which I did. </p>
  
  <p>I also searched and I found that I will likely need to use <a href="https://docs.mongodb.com/v3.2/reference/operator/aggregation/lookup/" rel="nofollow noreferrer"><code>$lookup</code></a>, however, I don't know how to move from that point forward. How do I do it ?</p>