Reputation: 383
So I have a JSON file which I have loaded into a dictionary. It has 8 different keys that it is storing information for. I am trying to create a search engine that returns the recipe that contains all the words in the search string and returns them. I change the string into a list of "tokens" that I will be used for searching.
Here is an example of some of the information stored in the dictionary. A recipe should be returned as long as the tokens are located in either the title, categories, ingredients or directions.
{
"title": "101 \"Whaler\" Fish Sandwich ",
"categories": [
"Sandwich",
"Cheese",
"Dairy",
"Fish",
"Tomato",
"Saut\u00e9",
"Kid-Friendly",
"Mayonnaise",
"Cornmeal",
"Lettuce",
"Cookie"
],
"ingredients": [
"1 cup whole milk",
"2 eggs",
"1 1/2 cups flour",
"1/4 cup yellow cornmeal",
"2 tablespoons chopped parsley",
"4 flounder fillets",
"Salt and pepper to taste",
"3 tablespoons canola oil",
"4 sesame-seed hamburger buns",
"4 leaves romaine lettuce",
"1/2 tomato, sliced",
"4 slices mild cheese, such as mild cheddar (optional)",
"1/2 cup mayonnaise",
"2 tablespoons pickle relish",
"1 tablespoon lemon juice",
"1 dash Tabasco sauce"
],
"directions": [
"1. In a medium-size bowl, whisk together the milk and eggs. In another medium-size bowl, mix together the flour, cornmeal, and parsley.",
"2. Season the fish with the salt and pepper.",
"3. Dredge the fish through the egg mixture, then coat it thoroughly with the flour mixture.",
"4. In a large saut\u00e9 pan, immediately heat the oil over medium-high heat. When it is hot but not smoking, add the fillets to the pan. Cook on one side until the batter is light golden brown, about 4 minutes. Carefully turn the fillets and cook for 2 to 3 minutes more. Using a slotted spatula, remove them from the pan and drain on paper towels.",
"5. Meanwhile, whisk together the tartar-sauce ingredients (if using).",
"6. Slice the buns and spread the tartar sauce (if using) on the insides. Place a fillet on each bottom bun, then top with the lettuce, tomato, and cheese, if desired."
],
"rating": 4.375,
"calories": 819.0,
"protein": 35.0,
"fat": 42.0
},
How would I be able to return the key in the dictionary that contains all the tokens in the string?
For example if there was a search string for "pancakes syrup" I would return the recipes on the dictionary that contain both "pancakes" and "syrup"?
This code creates a dictionary from the JSON file I am reading into Python:
file = open('recipes.json')
recipes = json.load(file)
This code cleans the input string
def tokenisation(input_string):
#functions to remove digits and punctuation and replace it with whitespace
d_translate = str.maketrans(string.digits, ' '*len(string.digits))
p_translate = str.maketrans(string.punctuation, ' '*len(string.punctuation))
#clean the string
new_string = input_string.translate(d_translate)
new_string = new_string.translate(p_translate)
new_string = new_string.lower()
#split the string
splitted_string = new_string.split(" ")
#make a list to store tokens in
tokens = []
#checking length of token
for token in splitted_string:
if len(token) > 3:
tokens.append(token)
return tokens
Then the actual search function (so far) is this:
def search(query, ordering = 'normal', count = 10):
token_list = tokenisation(query)
values = [recipes[k] for k in token_list]
But of course it's checking each token on it's own rather than the all the tokens being present.
Upvotes: 0
Views: 122
Reputation: 31619
I think what you want is the following:
def search(query, ordering = 'normal', count = 10):
token_list = tokenisation(query)
matching_recipes = []
for recipe in recipes:
recipe_tokens = []
for key in recipe:
if type(recipe[key]) != list:
continue
if type(recipe[key]) == str:
recipe_tokens.append(recipe[key])
for sentence in recipe[key]:
# Make sure all the words from the recipes are in one big list
recipe_tokens.extend([t for t in sentence.split()])
if all([tl in recipe_tokens for tl in token_list]):
# check if all the tokens from token_list are in the tokens of the recipe
matching_recipes.append(recipe)
return matching_recipes
Upvotes: 1