ソースを参照

Add getByIngredients endpoint: Filters recipe by list of ingredients

Tati 7 年 前
コミット
2798b5587a
2 ファイル変更37 行追加1 行削除
  1. 35 0
      ktchn/src/recipes/controller.ts
  2. 2 1
      ktchn/src/recipes/routes.ts

+ 35 - 0
ktchn/src/recipes/controller.ts

@@ -3,6 +3,7 @@ import { Recipe } from './model';
 import { IMongoService } from '../mongo';
 import { IMongoService } from '../mongo';
 import { ObjectId } from 'bson';
 import { ObjectId } from 'bson';
 import { json } from 'body-parser';
 import { json } from 'body-parser';
+import { FilterQuery } from 'mongodb';
 
 
 function validRecipe(data: any): Promise<Recipe> {
 function validRecipe(data: any): Promise<Recipe> {
   return new Promise(function(resolve, reject) {
   return new Promise(function(resolve, reject) {
@@ -10,6 +11,35 @@ function validRecipe(data: any): Promise<Recipe> {
   })
   })
 }
 }
 
 
+//{ $or: [{"ingredients.ingredients.name": { "$regex": "beef", "$options": "i"}}, {"ingredients.ingredients.name": { "$regex": "cheese", "$options": "i"}}, {"ingredients.ingredients.name": { "$regex": "mix", "$options": "i"}}]}
+
+
+const queryKeys: {[s: string]: (q: string) => {}} = {
+  'ing': (query: string) => {
+    return {
+      '$or': query.split(',').map(x => {
+        return {
+          'ingredients.ingredients.name': {
+            '$regex': x,
+            '$options': 'i'
+          }
+        };
+      })
+    }    
+  }
+}
+
+function queryParser(query: any): FilterQuery<any> {
+  let q = {};
+  for (const key of Object.keys(query)) {
+    q = {
+      ...q,
+      ...queryKeys[key](query[key]),
+    }
+  }
+  return q;
+}
+
 const save = (db: IMongoService) => ({ body }: Request, res: Response, next: NextFunction): Promise<any> => {
 const save = (db: IMongoService) => ({ body }: Request, res: Response, next: NextFunction): Promise<any> => {
   return validRecipe(body).then(
   return validRecipe(body).then(
     recipe => db.insertOne(recipe).then(
     recipe => db.insertOne(recipe).then(
@@ -29,9 +59,14 @@ const getAll = (db: IMongoService) => ({ query }: Request, res: Response, next:
   return db.find<Recipe>(query).then(recipes => res.json(recipes));
   return db.find<Recipe>(query).then(recipes => res.json(recipes));
 }
 }
 
 
+const getByIngredients = (db: IMongoService) => ({ query, params }: Request, res: Response, next: NextFunction) => {
+  return db.find<Recipe>(queryParser(query)).then(recipes => res.json(recipes))
+}
+
 export {
 export {
   save,
   save,
   getById,
   getById,
   get,
   get,
   getAll,
   getAll,
+  getByIngredients,
 }
 }

+ 2 - 1
ktchn/src/recipes/routes.ts

@@ -1,7 +1,7 @@
 import { Request, Response, Router, NextFunction } from "express";
 import { Request, Response, Router, NextFunction } from "express";
 import Scrape from "./scrape";
 import Scrape from "./scrape";
 import { Recipe } from './model';
 import { Recipe } from './model';
-import { save, get, getById, getAll } from './controller';
+import { save, get, getById, getAll, getByIngredients } from './controller';
 import MongoClient from 'mongodb';
 import MongoClient from 'mongodb';
 import { mongoService, IMongoService } from '../mongo';
 import { mongoService, IMongoService } from '../mongo';
 import piddleware from '../promise-all-middleware';
 import piddleware from '../promise-all-middleware';
@@ -19,6 +19,7 @@ class RecipeRoutes {
   private init() {
   private init() {
     this.router.get("/all/", piddleware([getAll(this.RecipeDB)]));
     this.router.get("/all/", piddleware([getAll(this.RecipeDB)]));
     this.router.get("/query/", piddleware([get(this.RecipeDB)]));
     this.router.get("/query/", piddleware([get(this.RecipeDB)]));
+    this.router.get("/ingredients/", piddleware([getByIngredients(this.RecipeDB)]));
     this.router.get("/id/:id", piddleware([getById(this.RecipeDB)]));
     this.router.get("/id/:id", piddleware([getById(this.RecipeDB)]));
     
     
     this.router.post("/", piddleware([save(this.RecipeDB)]));
     this.router.post("/", piddleware([save(this.RecipeDB)]));