我对Python和MongoDB还是很陌生,正在研究我的项目时。 在我的项目中,我有一个MongoDB文档,看起来像运行以下命令后的样子:
db.materials.insertOne({
"structure": {
"sites": [
{
"xyz": [
11,
12,
13
],
},
{
"xyz": [
21,
22,
23
],
},
{
"xyz": [
31,
32,
33
],
}
]
}})
我想要的是生成一个结合每个“ xyz”列表的第3个元素的python数组。即我希望数组为[13,23,33]。在此示例中,我们只有3个“ xyz”列表,在我的实际代码中,我任意地有许多“ xyz”列表。
在提取每个列表的第三个组件之前,我打算将所有xyz字段合并为一个列表。但是,在我对如何进行操作感到困惑之前,我只能设法做到一半。这是我在卡住之前尝试过的方法:
for m in tqdm(db.materials.find({structure: {$exists: true}}, {"structure.sites.xyz":1})):
try:
struc = m[structure]
site = struc[sites]
coord = site[xyz]
在尝试获取每个xyz的列表后,我在这里遇到了瓶颈。 给出的错误是:
coord = site["xyz"]
TypeError: list indices must be integers or slices, not str
当我没有以任何方式指定索引时,我对列表索引如何变成字符串而不是整数感到困惑。另外,如果我需要特别指定索引,该如何容纳文档中任意数量的“ xyz”列表?
我想知道的另一个问题是如何将每个“ xyz”列表的第3个元素提取到数组中,尽管我还没有涉及到这一部分。
我知道此处显示的尝试次数有限,但这确实是我可以做的所有工作,然后再空白下一步。任何指令及其背后的逻辑都将受到赞赏。
最佳 Yaze
答案 0 :(得分:0)
您的_.map(services, "service");
值是字典的列表,而不是字典本身,您将需要过滤或迭代该列表以访问每个字典。
也要警惕,如果站点列表包含除 “ xyz”之外的任何站点,例如
sites
您的投影将导致返回的值包含:
"structure":{"sites":[{"xyz":[1, 2, 3]}, {"z":[4, 5, 6]}, {"x":[7, 8, 9]}]}}
这只是意味着您需要进行测试以确保当前对象具有“ xyz”,因此不会出现键错误。
这里又快又脏:
{"sites":[{"xyz":[1, 2, 3]}, {}, {}]}
输入集合包含4个文档:
conn = MongoClient()
db = conn["test"]
result = list()
for doc in db.materials.find({"structure.sites.xyz":{"$exists":1,_id:0}},{"structure.sites.xyz":1}):
struct = doc["structure"]
sites = struct["sites"]
dsites = list()
for s in sites:
if s.has_key("xyz"):
dsites.append(s["xyz"][2])
result.append(dsites)
print result
这将产生:
{"structure":{"sites":[{"xyz":[11, 12, 13 ]}, {"xyz":[21, 22, 23 ]}, {"xyz":[31, 32, 33 ]}]}}
{"structure":{"sites":[{"xyz":[1, 2, 3 ]}, {"xyz":[4, 5, 6 ]}, {"xyz":[7, 8, 9 ]}]}}
{"structure":{"sites":[{"z":[1, 2, 3 ]}, {"y":[4, 5, 6 ]}, {"x":[7, 8, 9 ]}]}}
{"structure":{"sites":[{"xyz":[1, 2, 3 ]}, {"z":[4, 5, 6 ]}, {"x":[7, 8, 9 ]}]}