2017-06-15 54 views
1

我有以下格式我蒙戈实例文档中检索特定元素的数据,查找查询发现MongoDB中

{ 
"_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b70", 
"fname" : "john", 
"created_date" : ISODate("2017-05-24T01:13:06.829Z"), 
"customProp" : [ 
    [ 
     "customX","{\"some data related to X \"}" 
    ], 
    [ 
     "customY","{\"some data related to Y \"}" 
    ], 
    [ 
     "customZ","{\"some data related to Z \"}" 
    ] 
] 

}

元素/值分别为“customX”,“customY “&”customZ“不一定在所有文档中。如何检索“customProp”数组的第二个元素中的所有值,在本文档中它包含“customZ”?

我能使用下面的查询过滤&找到所有这些有“customZ”元素的文件,

db.getCollection('col1').find({$and : [{"customProp":{$elemMatch:{0:"customZ"}}}, {"created": { $gte: ISODate("2017-05-22T00:00:00.000Z") }}] },{"created":1}).limit(1) .pretty() 

输出:

{ 
     "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b45", 
     "created" : ISODate("2017-05-24T01:13:06.829Z") 
} 

而是寻找一种方法来检索所有数组第二个元素中第一个值为“customZ”的值。

预期的结果:

{ 
    "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b45", 
    "created" : ISODate("2017-05-24T01:13:06.829Z"), 
    "customPro": ["customZ","{\"some data related to Z \"}"] 
    } 

我很好,如果我的查询只返回

{ 
"{\"some data related to Z \"}" 
} 
+0

如果是我,我会改变我的数据模型,这样我就不会在对象中存储JSON字符串。而是存储对象的实际属性。 – bhspencer

+0

@Veeram其实很不一样。另外,OP实际上已经知道如何正确地将'elemMatch'应用到他们的案例中。这只是他们需要帮助的投影的另一部分。 –

回答

1

那么它是一个嵌套的数组,这是不是一个好主意,但你实际上匹配元素与$elemMatch表达式,因此您确实在customProp的“外部”数组中获得了该位置,从而允许您使用positional $ operator

db.getCollection('coll1').find(
    { 
    "customProp":{ "$elemMatch": { "0": "customZ" } }, 
    "created_date": { "$gte": ISODate("2017-05-22T00:00:00.000Z") } 
    }, 
    { "created_date": 1, "customProp.$": 1 } 
) 

那得到的结果:

{ 
     "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b70", 
     "created_date" : ISODate("2017-05-24T01:13:06.829Z"), 
     "customProp" : [ 
       [ 
         "customZ", 
         "{\"some data related to Z \"}" 
       ] 
     ] 
} 

哪里customProp当然仍嵌套数组中,但处理在Python个人文档时,你才可以数组索引访问属性:

doc['customProp'][0][1] 

这当然返回值:

'{"some data related to Z "}' 

同去es确实是JavaScript,它在语法上基本相同。作为壳例如:

db.getCollection('coll1').find(
    { 
    "customProp":{ "$elemMatch": { "0": "customZ" } }, 
    "created_date": { "$gte": ISODate("2017-05-22T00:00:00.000Z") } 
    }, 
    { "created_date": 1, "customProp.$": 1 } 
).map(function(doc) { 
    doc['customProp'] = doc['customProp'][0][1]; 
    return doc; 
}) 

和输出:

{ 
     "_id" : "08d4a242-08fb-07f7-46e5-8717a81d5b70", 
     "created_date" : ISODate("2017-05-24T01:13:06.829Z"), 
     "customProp" : "{\"some data related to Z \"}" 
} 

而这里的位置$投影确保仅存在一个返回的数组中的元素,所以该表示法是总是以从提取相同的所有文件结果。所以你从数据库中获得匹配的元素,并通过代码提取属性。

另请注意,您不需要$and,因为所有查询参数都已经是AND条件。这是MongoDB的默认设置,所以你不需要明确地表达它。如果没有它,看看它有多好。

+0

完美,谢谢。 – sqlcheckpoint