0

From this example document:

...
{
    "_id": ObjectId("5a934e000102030405000000"),
    "guild_id": 1234,
    "members": [
        ...
        {
            "member_id": 002,
            "name": "John Doe"
        },
        ...
    ]
}
...

I want to fetch an individual member object from the nested array so that I will be returned:

{"member_id": 002, "name": "John Doe"}

with which I can read in the member info.

How might one query by "member_id" like with 002 and get the desired result above? And with this, how would you also update the member "name" as well? Preferably in Python syntax, please, but any is fine as well.

1 Answer 1

1

aggregate

db.collection.aggregate([
  {
    "$match": {
      "members.member_id": "001"
    }
  },
  {
    "$unwind": "$members"
  },
  {
    "$match": {
      "members.member_id": "001"
    }
  },
  {
    "$replaceWith": "$members"
  }
])

mongoplayground


update

db.collection.update({
  "members.member_id": "001"
},
{
  "$set": {
    "members.$.name": "John"
  }
},
{
  "multi": false,
  "upsert": false
})

mongoplayground


python(fastapi) Edit this by yourself

from fastapi import FastAPI, Request, status, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pymongo import MongoClient
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModel

CONNECTION_STRING = "mongodb://localhost"
try:
    client = MongoClient(CONNECTION_STRING, serverSelectionTimeoutMS=3000)
    print('Connected ! Mongo version is', client.server_info()['version'])
except:
    print('Disconnected !')

app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}),
    )

templates = Jinja2Templates(directory="static")

@app.get("/")
async def root():
    db = get_database()
    c = db['key'].find({"_id":2})
    if (c):
        return {"message": c[0]}
    return {"message": c}

@app.get("/get/{id}")
async def root(id: int):
    db = get_database()
    c = list(db['key'].find({"_id":id}))
    return {"message": c}

def get_database():
    return client['test']
    
# This is added so that many files can reuse the function get_database()
if __name__ == "__main__":    
    print('__main__ !')
    # Get the database
    dbname = get_database()
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the quick response, this works but I will have to read more of this aggregate syntax as I'm still new to MongoDB!
Would you know how to query a specific member from a specific guild (using guild id)? Since a member can be found across different guilds.
Nevermind, I figured it out by simply adding the guild id inside the $match object in the aggregation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.