В настоящее время я пытаюсь принять пользовательский ввод, чтобы пользователь мог выполнять поиск в базе данных.
> db.test2.find().pretty()
{
"_id" : ObjectId("55de8a17f8389e208a1e7d7e"),
"name" : "john",
"favorites" : {
"vegetable" : "spinach",
"fruit" : "apple",
}
}
{
"_id" : ObjectId("55de8a17f8389e208a1f6gg4"),
"name" : "becky",
"favorites" : {
"vegetable" : "spinach",
"fruit" : "apple",
}
}
{
"_id" : ObjectId("55e3b6cbec2740181355b809"),
"name" : "liz",
"favorites" : {
"vegetable" : "spinach",
"fruit" : "banana",
}
}
В этом примере пользователь сможет искать любую комбинацию любимого овоща, фруктов или любимых овощей и любимых фруктов. Если пользователь вошел в шпинат для любимого овоща, все три будут возвращены. Однако, если пользователь вводит любимый овощ = шпинат и любимый фрукт = яблоко, будут возвращены только джон и беки.
В MongoDB вы можете определить, какой параметр вы хотите искать. Я пытаюсь написать свой код таким образом, что если пользователь оставляет поле пустым, его не следует искать.
я пытался
$query = array("favorites.vegetable" => "$userInput", "favorites.fruit" => "$userInput2");
но если одно из этих полей остается пустым, оно не вернет никаких результатов. Я думал о том, чтобы использовать инструкции if:
if ($vegetable == NULL)
{
$query = array("favorites.fruit" => "$fruit");
}
else if($fruit == NULL)
{
$query = array("favorites.vegetable" => "$vegetable");
}
else
{
$query = array("favorites.vegetable" => "$vegetable", "favorites.fruit" => "$fruit");
}
но если бы я хотел сделать свою базу данных доступной для поиска по более параметрам, у меня было бы слишком много условных операторов. Есть ли способ сделать мой поиск в Монго, когда поле остается пустым?
На самом деле возникает вопрос: "Откуда поступает вход?". Как будто у вас есть какая-то структура для ввода, тогда кодирование довольно просто следовать шаблону.
Как бы то ни было, с двумя основными переменными вы можете очистить код, чтобы просто конкретизировать свой запрос на основе того, что находится в переменных:
$query = array();
if ( $fruit != NULL ) {
$query["favorites.fruit"] = $fruit;
}
if ( $vegetable != NULL ) {
$query["favorites.vegetable"] = $vegetable;
)
Это означает, что вы либо закончите с $query
здесь, либо пустым, чтобы соответствовать всем, либо содержат конкретные аргументы (один или два) в зависимости от того, был ли контент нулевым или нет.
Если ваш ввод имеет некоторую структуру, то вы можете быть намного более динамичным:
$input = array("fruit" => "apple", "vegetable" => "spinach");
$query = array();
foreach ( $input as $key => $value ) {
$query["favorites.$key"] = $value;
}
Что делает то же самое, добавляя к $query
но более динамически, чем с отдельными переменными.
Также обратите внимание, что в отношении MongoDB ваша структура документа невелика. Вероятно, это должно выглядеть так:
{
"_id" : ObjectId("55de8a17f8389e208a1e7d7e"),
"name" : "john",
"favorites" : [
{ "type": "vegetable", "name": "spinach" },
{ "type": "fruit", "name": "apple" }
]
}
И хотя сначала может показаться, что запрос выходит сложнее, удаление "конкретных путей" в вашем запросе для таких ключей, как "овощ" и "фрукты", имеет много преимуществ, которые облегчают жизнь, а также primarilly "данные" могут быть "проиндексированы". Имена ключей не индексируются для поиска и, следовательно, неэффективны:
$input = array("fruit" => "apple", "vegetable" => "spinach");
$query = array();
foreach ( $input as $key => $value ) {
$query['$and'][] = array(
'favorites' => array(
'$elemMatch' => array(
'type' => $key, 'name' => $value
)
)
);
}
Какой хороший запрос использует $elemMatch
для поиска документов, содержащих "все" элементы массива, где "оба" "тип" и "имя" указанных элементов в вашем списке ввода.
В основном это похоже на JSON:
{
"$and": [
{ "favorites": {
"$elemMatch": {
"type": "fruit", "name": "apple"
}
}},
{ "favorites": {
"$elemMatch": {
"type": "vegetable", "name": "spinach"
}
}}
]
}
Все сводится к пониманию того, как манипулировать структурами данных на выбранном вами языке, и что "структуры данных" - это все запросы MongoDB, насколько это касается вашего языка.
Что касается изменения структуры, то кондите, что поиск людей, у которых есть "овощи" в своих "фаворитах", теперь становится следующим:
{ "favorites.type": "vegetable" }
Что хорошо, так как "favorite.type" можно индексировать, а не:
{ "favorites.vegetable": { "$exists": true } }
В то время как это может "технически" использовать индекс, на самом деле это не так хорошо. Поэтому желательно изменить способ представления схемы и обеспечить большую гибкость.