3

文档结构示例是:

{
   "dob": "12-13-2001",
   "name": "Kam",

   "visits": {
     "0": {
       "service_date": "12-5-2011",
       "payment": "40",
       "chk_number": "1234455",  
    },
     "1": {
       "service_date": "12-15-2011",
       "payment": "45",
       "chk_number": "3461234",  
    },
     "2": {
       "service_date": "12-25-2011",
       "payment": "25",
       "chk_number": "9821234",  
    } 
  } 
}


{
   "dob": "10-01-1998",
   "name": "Sam",

   "visits": {
     "0": {
       "service_date": "12-5-2011",
       "payment": "30",
       "chk_number": "86786464",  
    },
     "1": {
       "service_date": "12-15-2011",
       "payment": "35",
       "chk_number": "45643461234",  
    },
     "2": {
       "service_date": "12-25-2011",
       "payment": "20",
       "chk_number": "4569821234",  
    } 
  } 
}

在 PHP 中,我想列出所有付款少于“30”的“访问”信息(以及相应的“名称”)。

我只想打印“付款”<“30”而不是其他人的访问。这样的查询是可能的,还是我必须先使用搜索获取整个文档,然后使用 PHP 来选择这样的访问?

4

3 回答 3

18

在示例文档中,“付款”值以字符串形式给出,可能无法按预期使用 $lt 命令。对于此响应,我已将它们转换为整数。

MongoDB 无法进行通配符查询,因此对于给定的文档结构,必须知道子文档的键(0、1、2 等)。例如,以下查询将起作用:

> db.test.find({"visits.2.payment":{$lt:35}})

然而,

> db.test.find({"visits.payment":{$lt:35}})

在这种情况下不起作用,并且

> db.test.find({"visits.*.payment":{$lt:35}})

也不会返回任何结果。

为了能够查询嵌入的“访问”文档,您必须更改文档结构并将“访问”变成数组或嵌入文档,如下所示:

> db.test2.find().pretty()
{
    "_id" : ObjectId("4f16199d3563af4cb141c547"),
    "dob" : "10-01-1998",
    "name" : "Sam",
    "visits" : [
        {
            "service_date" : "12-5-2011",
            "payment" : 30,
            "chk_number" : "86786464"
        },
        {
            "service_date" : "12-15-2011",
            "payment" : 35,
            "chk_number" : "45643461234"
        },
        {
            "service_date" : "12-25-2011",
            "payment" : 20,
            "chk_number" : "4569821234"
        }
    ]
}

现在您可以在“visits”中查询所有嵌入的文档:

> db.test2.find({"visits.payment":{$lt:35}})

有关更多信息,请参阅有关点符号的 Mongo 文档:

http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

现在转到问题的第二部分:不可能只返回嵌入文档的条件子集。

对于任何一种文档格式,都不可能返回仅包含与查询匹配的子文档的文档。如果其中一个子文档与查询匹配,则整个文档与查询匹配,并将返回。

根据 Mongo 文档“检索字段子集”

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields

我们可以像这样返回部分嵌入文档:

> db.test2.find({"visits.payment":{$lt:35}},{"visits.service_date":1}).pretty()
{
    "_id" : ObjectId("4f16199d3563af4cb141c547"),
    "visits" : [
        {
            "service_date" : "12-5-2011"
        },
        {
            "service_date" : "12-15-2011"
        },
        {
            "service_date" : "12-25-2011"
        }
    ]
}

但是我们不能对某些子文档进行条件检索。我们能得到的最接近的是 $slice 运算符,但这不是有条件的,您必须首先知道数组中每个子文档的位置:

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-RetrievingaSubrangeofArrayElements

为了让应用程序只显示与查询匹配的嵌入文档,必须以编程方式完成。

于 2012-01-18T14:49:27.813 回答
1

你可以试试:

$results = $mongodb->find(array("visits.payment" => array('$lt' => 30)));

但我不知道它是否会起作用,因为它visits是一个对象。顺便说一句,从您发布的内容来看,它可以转移到数组中(或者应该因为数字属性名称容易引起混淆)

于 2012-01-17T22:00:42.137 回答
0

尝试 - db.test2.find({"visits.payment":"35"})

于 2016-03-21T15:35:12.053 回答