最新消息:20210917 已从crifan.com换到crifan.org

【已解决】Python的pymongo中随机输出一个集合的记录

Python crifan 606浏览 0评论
折腾:
【记录】用Flask实现测评系统的后端
期间,
需要实现MongoDB中,random随机获取一个,evaluation.question的collection
之前知道有find和find_one,但是只想要获取随机的一个
mongodb find return random
Random record from MongoDB – Stack Overflow
// Get one random document from the mycoll collection.
db.mycoll.aggregate([{ $sample: { size: 1 } }])
先去本地mongo命令行中试试
➜  mongodb mongo
MongoDB shell version v3.6.3
connecting to: 
mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
Server has startup warnings:
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten]
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten]
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2018-12-19T17:51:17.268+0800 I CONTROL  [initandlisten]
> show databases
Scholastic   0.039GB
admin        0.000GB
config       0.000GB
dialog       0.272GB
evaluation   0.000GB
gridfs      13.792GB
local        0.000GB
log          0.000GB
storybook    0.101GB
test         0.000GB
> use evaluation
switched to db evaluation
> show collections
question
> db.question.aggregate([{$sample: {size: 1}}])
{ "_id" : ObjectId("5c1777e1cc6df4563adf4b7e"), "question_number" : 304, "major_type" : "单选", "stem_text" : "When will the party start?", "max_answer_time" : 30, "difficulty" : "1.2", "audio_length" : 0, "ave_answer_time" : 15, "sub_questions" : [ { "option_type" : "text", "question_texts" : [ "" ], "options" : [ { "option_number" : 1, "option_image" : "", "option_text" : "In the morning." }, { "option_number" : 2, "option_image" : "", "option_text" : "In the evening." }, { "option_number" : 3, "option_image" : "", "option_text" : "At night." } ], "correct_option" : [ 2 ] } ], "checkpoint" : [ "reading", "general_reading", "句子理解", "", "" ], "stem_image" : "image/party board.png", "audio" : "", "audio_text" : "", "stem_type" : "mix" }
> db.question.aggregate([{$sample: {size: 1}}]).pretty
function () {
    this._prettyShell = true;
    return this;
}
> db.question.aggregate([{$sample: {size: 1}}]).pretty()
{
    "_id" : ObjectId("5c1777e2cc6df4563adf4cd1"),
    "question_number" : 643,
    "major_type" : "单选",
    "stem_text" : "Who ___ you maths last Sunday?",
    "max_answer_time" : 10,
    "difficulty" : 2,
    "audio_length" : 0,
    "ave_answer_time" : 5,
    "sub_questions" : [
        {
            "option_type" : "text",
            "question_texts" : [
                ""
            ],
            "options" : [
                {
                    "option_number" : 1,
                    "option_image" : "",
                    "option_text" : "taught"
                },
                {
                    "option_number" : 2,
                    "option_image" : "",
                    "option_text" : "teaches"
                },
                {
                    "option_number" : 3,
                    "option_image" : "",
                    "option_text" : "teach"
                }
            ],
            "correct_option" : [
                1
            ]
        }
    ],
    "checkpoint" : [
        "reading",
        "grammar",
        "",
        "",
        ""
    ],
    "stem_image" : "",
    "audio" : "",
    "audio_text" : "",
    "stem_type" : "text"
}
>
再去pymongo中试试是否支持
pymongo aggregate
Aggregation Examples — PyMongo 3.7.2 documentation
需要PyMongo版本>= 2.1.0
去看看此处版本
Pipfile
中只有:
flask-pymongo = "*"
没有版本,去看看pipenv graph
➜  EvaluationSystemServer git:(master) pipenv graph
Flask-Cors==3.0.7
  - Flask [required: >=0.9, installed: 1.0.2]
    - click [required: >=5.1, installed: 7.0]
    - itsdangerous [required: >=0.24, installed: 1.1.0]
    - Jinja2 [required: >=2.10, installed: 2.10]
      - MarkupSafe [required: >=0.23, installed: 1.1.0]
    - Werkzeug [required: >=0.14, installed: 0.14.1]
  - Six [required: Any, installed: 1.12.0]
Flask-PyMongo==2.2.0
  - Flask [required: >=0.11, installed: 1.0.2]
    - click [required: >=5.1, installed: 7.0]
    - itsdangerous [required: >=0.24, installed: 1.1.0]
    - Jinja2 [required: >=2.10, installed: 2.10]
      - MarkupSafe [required: >=0.23, installed: 1.1.0]
    - Werkzeug [required: >=0.14, installed: 0.14.1]
  - PyMongo [required: >=3.0, installed: 3.7.2]
Flask-RESTful==0.3.7
  - aniso8601 [required: >=0.82, installed: 4.0.1]
  - Flask [required: >=0.8, installed: 1.0.2]
    - click [required: >=5.1, installed: 7.0]
    - itsdangerous [required: >=0.24, installed: 1.1.0]
    - Jinja2 [required: >=2.10, installed: 2.10]
      - MarkupSafe [required: >=0.23, installed: 1.1.0]
    - Werkzeug [required: >=0.14, installed: 0.14.1]
  - pytz [required: Any, installed: 2018.7]
  - six [required: >=1.3.0, installed: 1.12.0]
gevent==1.3.7
  - greenlet [required: >=0.4.14, installed: 0.4.15]
gunicorn==19.9.0
python-dotenv==0.10.1
Flask-PyMongo==2.2.0
符合要求
Aggregation Examples — PyMongo 2.7.2 documentation
“Note
aggregate requires server version >= 2.1.0. The PyMongo aggregate() helper requires PyMongo version >= 2.3.”
不清楚到底是否支持了。
先去试试再说
python – Aggregate query in mongo works, does not in Pymongo – Stack Overflow
mongodb – how to find and then aggregate – Stack Overflow
pymongo and output of aggregate – Stack Overflow
此处有点诧异:
为何pymongo有2.7.2和3.7.2,都很新的版本
但是此处为何只有2.2.0啊
才想起来:Flask-PyMongo和pymongo 不是同一个吧?
搜:Flask-PyMongo
Flask-PyMongo — Flask-PyMongo 2.2.0.post3 documentation
才注意到是:
Flask-PyMongo==2.2.0
...
  - PyMongo [required: >=3.0, installed: 3.7.2]
即:
  • Flask-PyMongo:2.2.0
  • PyMongo:3.7.2
都是最新的,不用担心版本问题。
https://flask-pymongo.readthedocs.io/en/latest/
http://www.pythondoc.com/flask-pymongo/
没找到aggregate
用代码:
# for debug
randomPipline = [{ "$sample" : { "size": 1 } }]
log.debug("randomPipline=%s", randomPipline)
randomQuestion = questionCollection.aggregate(pipeline=randomPipline)
log.debug("randomQuestion=%s", randomQuestion)
randomQuestionType = type(randomQuestion)
log.debug("randomQuestionType=%s", randomQuestionType)
得到的是:
randomPipline=[{'$sample': {'size': 1}}]
randomQuestion=<pymongo.command_cursor.CommandCursor object at 0x1082eb320>
randomQuestionType=<class 'pymongo.command_cursor.CommandCursor'>
再看看怎么得到record
参考:
https://stackoverflow.com/questions/31082323/pymongo-and-output-of-aggregate
去加上: list()
https://stackoverflow.com/questions/38133529/aggregate-query-in-mongo-works-does-not-in-pymongo
“x=db.test.aggregate(aggregation_string)
print x
for r in x:
        min_age=r.items()[0]
        print(min_age[1])      #######output:      20”
【总结】
最后用代码:
randomPipline = [{ "$sample" : { "size": 1 } }]
log.debug("randomPipline=%s", randomPipline)
randomQuestionCursor = questionCollection.aggregate(pipeline=randomPipline)
log.debug("randomQuestionCursor=%s", randomQuestionCursor)
randomQuestionType = type(randomQuestionCursor)
log.debug("randomQuestionType=%s", randomQuestionType)
randomQuestionList = list(randomQuestionCursor)
log.debug("randomQuestionList=%s", randomQuestionList)
randomQuestion = randomQuestionList[0]
log.debug("randomQuestion=%s", randomQuestion)

randomQuestionId = str(randomQuestion["_id"])
log.debug("randomQuestionId=%s", randomQuestionId)
randomQuestion.pop("_id")
log.debug("randomQuestion=%s", randomQuestion)
randomQuestion["_id"] = randomQuestionId
log.debug("randomQuestion=%s", randomQuestion)

respDict["message"] = "Get next question ok"
respDict["data"] = randomQuestion
return jsonify(respDict)
可以得到想要的随机出来的单个record:
evaluation.py:117 get] randomPipline=[{'$sample': {'size': 1}}]
evaluation.py:119 get] randomQuestionCursor=<pymongo.command_cursor.CommandCursor object at 0x109e59860>
evaluation.py:121 get] randomQuestionType=<class 'pymongo.command_cursor.CommandCursor'>
evaluation.py:123 get] randomQuestionList=[{'_id': ObjectId('5c1777e1cc6df4563adf4aa6'), 'question_number': 88, ..., 'stem_type': 'empty'}]
evaluation.py:125 get] randomQuestion={'_id': ObjectId('5c1777e1cc6df4563adf4aa6'), 'question_number': 88, ... 'stem_type': 'empty'}
evaluation.py:128 get] randomQuestionId=5c1777e1cc6df4563adf4aa6
evaluation.py:130 get] randomQuestion={'question_number': 88, ... 'stem_type': 'empty'}
evaluation.py:132 get] randomQuestion={'question_number': 88, ... 'stem_type': 'empty', '_id': '5c1777e1cc6df4563adf4aa6'}
postman测试的flask的接口返回结果效果

转载请注明:在路上 » 【已解决】Python的pymongo中随机输出一个集合的记录

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
92 queries in 0.180 seconds, using 23.32MB memory