2017-06-15 79 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