2014-02-12 38 views
2

阵列我有一个集合,如下所示: -

{ "_id" : 1, "grades" : [ 70, 87, 90 ] } 
{ "_id" : 2, "grades" : [ 90, 88, 92 ] } 

我使用下面的查询: -

db.students.find({ semester: 1, grades: { $gte: 85 } }, 
        { "grades.$": 1 }) 

我得到的结果如下: -

{ "_id" : 1, "grades" : [ 87 ] } 
{ "_id" : 2, "grades" : [ 90 ] } 

现在我的问题是,当我在字段级上使用$ gte时,它将检查数组中是否有任何元素匹配条件,修改文件。那么为什么我得到第一个文档的输出为87而不是70.我知道我们已经指定了一个相等条件“等级:{$ gte:85}”,但它已经将完整的文档返回给我并投影了第一个字段。那么为什么87是输出?

回答

1

那么,为什么我得到第一个文档输出为87和70不会

因为你特别要求它。这正是positional projection operator $的用途:它返回匹配查询的第一个元素,因此投影grades.$ : 1将返回一个数组,其中包含匹配标准的数组中的第一个也是唯一的第一个元素,即第一个元素大于或等于85.

它可能会令人恼怒,它仍然是一个数组 - 毕竟,因为它总是只有一个元素,它们只能为您提供像grades:87这样的值。不过,这是MongoDB中的一种模式:除非您使用聚合框架,否则它不会修改数据的结构,从而更容易将查询结果映射到静态类型的语言。

如果你想拥有整个数组,那么你就不需要投影都:

db.students.find({ semester: 1, grades: { $gte: 85 } }) 
{ "_id" : 1, semester: 1, "grades" : [ 70, 87, 90 ] } 
{ "_id" : 2, semester: 1, "grades" : [ 90, 88, 92 ] } 

如果只想数组(不是第一匹配元素)的第一个元素,你可以使用$slice

db.students.find({semester: 1, grades: { $gte: 85 } },{ "grades": {$slice : 1}}); 
{ "_id" : 1, semester: 1, "grades" : [ 70 ] } 
{ "_id" : 2, semester: 1, "grades" : [ 90 ] } 
+0

我有一个疑问,在这里,我有什么在我的脑海的是,当我们查询任何与投影则发生两件事情。 1)光标被返回以满足条件,以便在这种情况下,它是文件{ “_id”:1,学期:1, “等级”:[70,87,90]} { “_id”:2 ,学期:1,“成绩”:[90,88,92]}。 2)现在,投影应用,我们得到这是 第一个元素{ “_id”:1,学期:1, “等级”:[70]} { “_id”:2,学期:1, “等级” :[90]} 那么为什么87在第一场呢? $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ – Saumyaraj

+1

的投影光标的一部分,它不是发生*之后*光标已返回的结果,但光标迭代过程中使用,所以它有关于匹配过程的知识,是的,否则将无法进行二次操作做它做的事。 – mnemosyn