查询 MongoDB 以使用 pymongo 通过 Django 中的嵌套对象键范围获取具有 skip/limit 的嵌套数组
Query MongoDB to fetch a nested array with skip/limit by nested object key range in Django using pymongo
我正在用 pymongo 学习 Django。
我有一个 MongoDB 集合,我在其中存储了一些单词及其在某些书中的年度出现次数。
文档以下列格式存储在 MongoDB 中:
{
"_id":{
"$oid":"625c51eec27c99b793074501"
},
"word":"entropy",
"occurrence":13,
"year":{
"1942":[
{
"book":{
"$oid":"625c51eec27c99b7930744f9"
},
"number":8,
"sentence":[
1,
288,
322,
1237,
2570,
2585,
2617,
2634
]
}
],
"1947":[
{
"book":{
"$oid":"625c5280c27c99b793077042"
},
"number":5,
"sentence":[
377,
2108,
2771,
3467,
3502
]
}
]
}
}
现在我想获取 skip 和 limit 的句子列表(以及相应的书 ID) _id 和特定的 year 范围。
例如,
- 我想获取一个数组,其中每一行都是一个包含 'year'、'book' 和 'sentence' 的字典。
- 数组将按_id和year范围查询。
- A skip 和 limit 将应用于 sentence list
这是使用 Django 和 pymongo 的可能任务吗?如果是,最快的方法是什么?
到目前为止我已经这样做了:
search= {'$and': [{"_id": word_id_obj, "year.1942": {"$exists": 1}}]}
datalist= []
word_docs= wordcollec.find(search, {'year': 1, '_id': 0}).skip(1).limit(5)
sentlist['recordsFiltered']+= wordcollec.count_documents(search)
for b in word_docs:
year_data= b['year'][1942]
for by in year_data:
i= i+1
this_word= {'serial': i, 'year': cyear, 'book': str(by['book'])}
datalist.append(this_word)
但显然,它没有给出预期的结果,因为 skip 和 limit 正在应用于根文档对象。 year 也有一个固定值,没有范围。
似乎可以使用“$slice”。但是我想不通。
感谢您阅读到这里。如果你能抛出一些光,还有更多。
这是一种方法:
... fetch an array where each row will be a dictionary
containing 'year', 'book' and 'sentence'.
db.collection.aggregate([
{ "$set": { "designWorkAround": { "$objectToArray": "$year" } } },
{ "$set": {
"designWorkAround": {
"$map": {
"input": "$designWorkAround",
"as": "yearArray",
"in": {
"year": "$$yearArray.k",
"books": {
"$map": {
"input": "$$yearArray.v",
"as": "bookArray",
"in": {
"bookId": "$$bookArray.book",
"number": "$$bookArray.number",
"sentence": "$$bookArray.sentence"
}
}
}
}
}
}
}
},
{ "$unwind": "$designWorkAround" },
{ "$unwind": "$designWorkAround.books" },
{ "$project": {
"_id": 0,
"year": "$designWorkAround.year",
"book": "$designWorkAround.books.bookId",
"sentence": "$designWorkAround.books.sentence"
}
}
])
在 mongoplayground.net 上试用。
我不知道您可能想要的所有数据生成或查询,但我可能会重新设计该集合,并且每本书有一个文档,其中包含文档中的所有相关字段。这将使查询、索引等更简单、更高效。
我正在用 pymongo 学习 Django。
我有一个 MongoDB 集合,我在其中存储了一些单词及其在某些书中的年度出现次数。
文档以下列格式存储在 MongoDB 中:
{
"_id":{
"$oid":"625c51eec27c99b793074501"
},
"word":"entropy",
"occurrence":13,
"year":{
"1942":[
{
"book":{
"$oid":"625c51eec27c99b7930744f9"
},
"number":8,
"sentence":[
1,
288,
322,
1237,
2570,
2585,
2617,
2634
]
}
],
"1947":[
{
"book":{
"$oid":"625c5280c27c99b793077042"
},
"number":5,
"sentence":[
377,
2108,
2771,
3467,
3502
]
}
]
}
}
现在我想获取 skip 和 limit 的句子列表(以及相应的书 ID) _id 和特定的 year 范围。
例如,
- 我想获取一个数组,其中每一行都是一个包含 'year'、'book' 和 'sentence' 的字典。
- 数组将按_id和year范围查询。
- A skip 和 limit 将应用于 sentence list
这是使用 Django 和 pymongo 的可能任务吗?如果是,最快的方法是什么?
到目前为止我已经这样做了:
search= {'$and': [{"_id": word_id_obj, "year.1942": {"$exists": 1}}]}
datalist= []
word_docs= wordcollec.find(search, {'year': 1, '_id': 0}).skip(1).limit(5)
sentlist['recordsFiltered']+= wordcollec.count_documents(search)
for b in word_docs:
year_data= b['year'][1942]
for by in year_data:
i= i+1
this_word= {'serial': i, 'year': cyear, 'book': str(by['book'])}
datalist.append(this_word)
但显然,它没有给出预期的结果,因为 skip 和 limit 正在应用于根文档对象。 year 也有一个固定值,没有范围。
似乎可以使用“$slice”。但是我想不通。
感谢您阅读到这里。如果你能抛出一些光,还有更多。
这是一种方法:
... fetch an array where each row will be a dictionary containing 'year', 'book' and 'sentence'.
db.collection.aggregate([
{ "$set": { "designWorkAround": { "$objectToArray": "$year" } } },
{ "$set": {
"designWorkAround": {
"$map": {
"input": "$designWorkAround",
"as": "yearArray",
"in": {
"year": "$$yearArray.k",
"books": {
"$map": {
"input": "$$yearArray.v",
"as": "bookArray",
"in": {
"bookId": "$$bookArray.book",
"number": "$$bookArray.number",
"sentence": "$$bookArray.sentence"
}
}
}
}
}
}
}
},
{ "$unwind": "$designWorkAround" },
{ "$unwind": "$designWorkAround.books" },
{ "$project": {
"_id": 0,
"year": "$designWorkAround.year",
"book": "$designWorkAround.books.bookId",
"sentence": "$designWorkAround.books.sentence"
}
}
])
在 mongoplayground.net 上试用。
我不知道您可能想要的所有数据生成或查询,但我可能会重新设计该集合,并且每本书有一个文档,其中包含文档中的所有相关字段。这将使查询、索引等更简单、更高效。