Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MongoDB搜索的用户输入_Php_Mongodb_Mongodb Query - Fatal编程技术网

Php MongoDB搜索的用户输入

Php MongoDB搜索的用户输入,php,mongodb,mongodb-query,Php,Mongodb,Mongodb Query,我目前正在尝试接受用户输入,以便用户能够搜索数据库 > db.test2.find().pretty() { "_id" : ObjectId("55de8a17f8389e208a1e7d7e"), "name" : "john", "favorites" : { "vegetable" : "spinach", "fruit" : "apple", } } { "_id" : ObjectId("55de8a17f

我目前正在尝试接受用户输入,以便用户能够搜索数据库

> 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",
    }
}
在本例中,用户可以搜索一个人最喜欢的蔬菜、水果或他们最喜欢的蔬菜和水果的任意组合。如果用户输入菠菜作为最喜欢的蔬菜,这三种蔬菜都将返回。但是,如果用户输入favorite蔬菜=菠菜,favorite水果=苹果,则只返回john和becky

在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");
}
但是,如果我想通过更多参数来搜索我的数据库,我会有太多的条件语句。有什么方法可以让我的Mongo搜索在字段留空时识别出来吗?

问题是,“输入来自哪里?”。就好像您对输入有某种结构一样,按照一种模式进行编码是非常简单的

实际上,使用两个基本变量,您可以清理代码,根据变量中的内容简单地构造查询:

$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
附加到
$query
来做同样的事情,但与单个变量相比,它的方式更加动态

还要注意的是,就MongoDB而言,您的文档结构不是很好。它可能真的应该是这样的:

{
    "_id" : ObjectId("55de8a17f8389e208a1e7d7e"),
    "name" : "john",
    "favorites" : [
        { "type": "vegetable", "name": "spinach" },
        { "type": "fruit", "name": "apple" }
    ]
}
虽然查询一开始看起来可能更复杂一些,但删除查询中的“特定路径”键(如“蔬菜”和“水果”)有很多好处,使生活更轻松,而且基本上“数据”可以“索引”。关键字名称不可用于索引搜索,因此效率低下:

$input = array("fruit" => "apple", "vegetable" => "spinach");

$query = array();

foreach ( $input as $key => $value ) {
  $query['$and'][] = array(
    'favorites' => array(
      '$elemMatch' => array(
          'type' => $key, 'name' => $value
      )
    )
  );
}
这是一个很好的查询,用于查找包含“all”数组元素的文档,其中“type”和“name”是输入列表中指定项的“type”和“name”

在JSON中基本上如下所示:

{
  "$and": [
    { "favorites": {
      "$elemMatch": {
          "type": "fruit", "name": "apple"
      }
    }},
    { "favorites": {
      "$elemMatch": {
          "type": "vegetable", "name": "spinach"
      }
    }}
  ]
}
归根结底,要知道如何使用所选语言操作数据结构,“数据结构”就是MongoDB查询的全部内容,就您的语言而言

至于结构的变化,那么有条件的是,找到那些在他们的“最爱”中有“蔬菜”的人现在变成了这样:

{ "favorites.type": "vegetable" }
这很好,因为“favorites.type”可以索引,而不是:

{ "favorites.vegetable": { "$exists": true } }

虽然这可以“从技术上”使用一个索引,但它并没有以这样一种好的方式真正做到这一点。因此,更改模式的表示方式是可取的,并提供了更大的灵活性。

非常感谢您的详细回答!这真的帮了我大忙。我将考虑如何构建数据库。再次感谢你!