Mongodb - 查询深层嵌套数组

时间:2014-05-27 01:22:06

标签: mongodb aggregation-framework

我已经在SO和Google上提出了类似的问题2天了。这是文件

{
    "rows" : [
        {
            "company" : "1 Gables Inn Bed & Breakfast",
            "address" : " 318 Quapaw Avenue Hot Springs",
            "a_url" : " AR 71901 Phone: 501-623-7576 ",
            "json" : {
                "results" : [
                    {
                        "address_components" : [
                            {
                                "long_name" : "318",
                                "short_name" : "318",
                                "types" : [ "street_number" ]
                            },
                            {
                                "long_name" : "Quapaw Avenue",
                                "short_name" : "Quapaw Ave",
                                "types" : [ "route" ]
                            },
                            {
                                "long_name" : "Hot Springs",
                                "short_name" : "Hot Springs",
                                "types" : [ "locality", "political" ]
                            },
                            {
                                "long_name" : "Hot Springs",
                                "short_name" : "Hot Springs",
                                "types" : [ "administrative_area_level_3", "political" ]
                            },
                            {
                                "long_name" : "Garland County",
                                "short_name" : "Garland County",
                                "types" : [ "administrative_area_level_2", "political" ]
                            },
                            {
                                "long_name" : "Arkansas",
                                "short_name" : "AR",
                                "types" : [ "administrative_area_level_1", "political" ]
                            },
                            {
                                "long_name" : "United States",
                                "short_name" : "US",
                                "types" : [ "country", "political" ]
                            },
                            {
                                "long_name" : "71901",
                                "short_name" : "71901",
                                "types" : [ "postal_code" ]
                            }
                        ],
                        "formatted_address" : "318 Quapaw Avenue, Hot Springs, AR 71901, USA",
                        "geometry" : {
                            "bounds" : {
                                "northeast" : {
                                    "lat" : 34.508227,
                                    "lng" : -93.05744779999999
                                 },
                                "southwest" : {
                                    "lat" : 34.50822,
                                    "lng" : -93.05746420000001
                                 }
                             },
                             "location" : {
                                 "lat" : 34.508227,
                                 "lng" : -93.05746420000001
                             },
                             "location_type" : "RANGE_INTERPOLATED",
                             "viewport" : {
                                 "northeast" : {
                                     "lat" : 34.5095724802915,
                                     "lng" : -93.05610701970851
                                 },
                                 "southwest" : {
                                     "lat" : 34.5068745197085,
                                     "lng" : -93.05880498029151
                                 }
                             }
                         },
                         "types" : [ "street_address" ]
                     }
                 ],
                 "status" : "OK"
             }
         },
         {
             "company" : "1000 Acres Retreat House",
             "address" : " 122 Russell Street  Hot Springs ",
             "a_url" : " AR 71901 501-318-4117  Website ",
             "json" : {
                 "results" : [
                     {
                         "address_components" : [
                             {
                                 "long_name" : "122",
                                 "short_name" : "122",
                                 "types" : [ "street_number" ]
                             },
                             {
                                 "long_name" : "Russell Street",
                                 "short_name" : "Russell St",
                                 "types" : [ "route" ]
                             },
                             {
                                 "long_name" : "Hot Springs",
                                 "short_name" : "Hot Springs",
                                 "types" : [ "locality", "political" ]
                             },
                             {
                                 "long_name" : "Hot Springs",
                                 "short_name" : "Hot Springs",
                                 "types" : [ "administrative_area_level_3", "political" ]
                             },
                             {
                                 "long_name" : "Garland County",
                                 "short_name" : "Garland County",
                                 "types" : [ "administrative_area_level_2", "political" ]
                             },
                             {
                                 "long_name" : "Arkansas",
                                 "short_name" : "AR",
                                 "types" : [ "administrative_area_level_1", "political" ]
                             },
                             {
                                 "long_name" : "United States",
                                 "short_name" : "US",
                                 "types" : [ "country", "political" ]
                             },
                             {
                                 "long_name" : "71901",
                                 "short_name" : "71901",
                                 "types" : [ "postal_code" ]
                             }
                         ],
                         "formatted_address" : "122 Russell Street, Hot Springs, AR 71901, USA",
                         "geometry" : {
                             "location" : {
                                 "lat" : 34.5313788,
                                 "lng" : -93.05564799999999
                             },
                             "location_type" : "ROOFTOP",
                             "viewport" : {
                                 "northeast" : {
                                     "lat" : 34.5327277802915,
                                     "lng" : -93.05429901970848
                                 },
                                 "southwest" : {
                                     "lat" : 34.5300298197085,
                                     "lng" : -93.0569969802915
                                 }
                             }
                         },
                         "types" : [ "street_address" ]
                     }
                 ],
                 "status" : "OK"
             }
         }
    ]
}

我想知道,这些行来自Google地理编码结果

我要做的是找到并提取" postal_code"对于每个地址。 " postal_code"的位置因请求而异,因此我们不能依赖于数组中固定的预期位置。相反,我们必须确定"类型"等于" postal_code",然后提取相应的" long_name"。最终" postal_code"回到MySQL,所以我想这里的目标是'#34; flatten"文件。

如果它对任何人都有帮助,这就是Mongodb中记录的样子:

mongo screenshot

每个记录都在它自己的数组行中,这似乎使查询复杂化,因为我尝试了以下变体:

db.AR.find({ 'results.address_components.types': { $in: ["postal_code"] } }).toArray()

db.AR.find({ 'rows.results.address_components.types': { $in: ["postal_code"] } }).toArray()

...似乎无法获得任何结果。没什么,齐尔奇。纳达。

不过,这是我第一次使用MongoDB,因为它似乎是最适合此类问题的工具。我也尝试了MySQL" json_extract" UDF功能,但我似乎无法取得任何进展。所以我想我所说的是,如果我让它变得比它需要的更困难 - 而且有人有更好的方法 - 我愿意接受建议。

无耻

1 个答案:

答案 0 :(得分:5)

你真正想要的是aggregation framework,它不仅用于“聚合”结果,还用于“文档重塑”,这是你问题的一部分。您也没有按要求通过正确的路径查询

db.AR.aggregate([
    { "$unwind": "$rows" },
    { "$unwind": "$rows.json.results" },
    { "$unwind": "$rows.json.results.address_components" },
    { "$match": {
        "rows.json.results.address_components.types": "postal_code"
    }},
    { "$project": {
        "company": "$rows.company",
        "address": "$rows.address",
        "postal_code": "$rows.json.results.address_components.long_name"
    }}
])

给你一个结果:

{
    "_id" : ObjectId("5383eebcdef83b11e3d71ec4"),
    "company" : "1 Gables Inn Bed & Breakfast",
    "address" : " 318 Quapaw Avenue Hot Springs",
    "postal_code" : "71901"
}
{
    "_id" : ObjectId("5383eebcdef83b11e3d71ec4"),
    "company" : "1000 Acres Retreat House",
    "address" : " 122 Russell Street  Hot Springs ",
    "postal_code" : "71901"
}

由于文档包含嵌套数组,因此在使用$unwind将结果过滤到最里面types字段中包含“postal_code”的结果之前,必须$match所有这些阵列。 $unwind语句对文档进行“反规范化”,实际上为每个数组条目创建了一个文档“copy”。

最后,您可以使用$project将文档重新塑造或“展平”为您想要的结果样式。

您还可以阅读文档中的aggregation framework operators了解更多信息。