Unknowntiou
Unknowntiou

Reputation: 327

Select multiple values from a document

Background

I have data stored in the following format

{
    "player_id": "VU3R5HNTAGMK",
    "markers": {
        "BICF2P964092": "GC",
        "BICF2G630653981": "CG",
        "BICF2P483996": "CT",
        "BICF2S23452916": "CG",
        "chr26_19147949": "TC",
    }
}

You can imagine i have data stored for multiple players and each has a unique player_id and they all have varying number of markers with different marker values.

In the above case a marker is BICF2P964092 and it's marker value is GC.

I am trying to query my mongo db in various ways. One obvious way is by using player_id. To do that I do the following col.find({"player_id": "VU3R5HNTAGMK"})

Another thing i want to do is maybe I just want to know value of a specific marker for a specific player. So for that I can do the following col.find({"player_id": "VU3R5HNTAGMK"}, {'markers.BICF2P964092'})

ISSUE

I also want to be able to get values for multiple markers for a specific player and i am not able to do so. I have tried the following with no luck.

col.find({"player_id": "VU3R5HNTAGMK"},{'markers': {'$in': ["BICF2P964092", "chr26_19147949"]}})

col.find({"player_id": "VU3R5HNTAGMK"}, {'markers.BICF2P964092'}, {'markers.chr26_19147949'})

I would really appreciate it if someone can help me write a query where i can get multiple marker values for specified marker and player_id

Upvotes: 2

Views: 375

Answers (3)

gosalia
gosalia

Reputation: 302

You can simply do the following

col.find({“player_id”: “VU3R5HNTAGMK”}, {“markers.” + m: 1 for m in [“ BICF2P964092", “BICF2G630653981”]})

Upvotes: 1

hhharsha36
hhharsha36

Reputation: 3349

@Belly Buster solution is good if you want to handle this using python.

But, there is a way to completely handle this on the MongoDB side using Aggregation.

You can combine $objectToArray, $filter, and $arrayToObject operators in $project stage.

collection.aggregate([
  {
    "$match": {
      "player_id": "VU3R5HNTAGMK"  # <-- All your match conditons
    }
  },
  {
    "$project": {
      "player_id": 1,  # All the other keys which you want to project
      "markers": {
        "$arrayToObject": {
          "$filter": {
            "input": {
              "$objectToArray": "$markers"
            },
            "as": "elem",
            "cond": {
              "$in": [
                "$$elem.k",
                [
                  # <-- List of key names you want to project
                  "BICF2G630653981",
                  "BICF2P483996"
                ]
              ]
            },
          },
        },
      },
    }
  },
])

Note: You have to use MongoDB version >= 3.4.4 for this aggregation query to work.

Upvotes: 1

Belly Buster
Belly Buster

Reputation: 8814

As you've tagged this pymongo, you might be as best to process the marker values in python after the find; e.g.

docs = col.find({"player_id": "VU3R5HNTAGMK"})

for doc in docs:
    for marker, value in doc.get('markers').items():
        if marker in ["BICF2P964092", "chr26_19147949"]:
            print(marker, value)

Upvotes: 1

Related Questions