Xopa
Xopa

Reputation: 131

Searching for a record where an array contains an item

I'm currently trying to find out how to search for a mongoDB document that contains an array. I want to find any records that have an array containing value X. Below is an example of my document structure.

{
"_id" : ObjectId("577d5c3c2c7e949307270d43"),
"name" : "Cruise Data",
"author" : "test",
"source" : "",
"headings" : [ 
    "\"Arrival Date\"", 
    "Vessel", 
    "Cruise Call", 
    "Hash Items", 
    "Row Hash"
],
"data" : {
    "1" : [ 
        "05 Jan 2016", 
        "Black Watch (Fred Olsen)", 
        "Turnaround", 
        "b5740452f7d83a243d84fc3d8f72b312"
    ],
    "2" : [ 
        "26 Apr 2016", 
        "Boudicca (Fred Olsen)", 
        "Transit", 
        "0bf1b79a58b4bb943763f3745543497b"
    ],
},
"updated_at" : ISODate("2016-07-06T19:30:04.799Z"),
"created_at" : ISODate("2016-07-06T19:30:04.799Z")

}

The value I'm searching for is the MD5 hash in the data object. (ex: 0bf1b79a58b4bb943763f3745543497b). I've tried a couple of variations of db.getCollection('datasets').find({data: {}) but had no luck. Is someone able to point me in the right direction?

Upvotes: 0

Views: 63

Answers (1)

Manish Kapoor
Manish Kapoor

Reputation: 536

For this you need to model your field 'data' in such a format that it has known keys. For example:

"data": [
    {
        id: '1',
        date: "05 Jan 2016",
        name: "Black Watch (Fred Olsen)",
        type: "Turnaround",
        md5: "b5740452f7d83a243d84fc3d8f72b312"
    },
    {
        id: '2',
        date: "26 Apr 2016",
        name: "Boudicca (Fred Olsen)",
        type: "Transit",
        md5: "0bf1b79a58b4bb943763f3745543497b"
    }
]

And then you can find it easily by following query: db.datasets.find({'data.md5':'0bf1b79a58b4bb943763f3745543497b'})

If it is impossible to change the data model, then you can use $where and write your custom javascript logic to find the element(s). See documentation: https://docs.mongodb.com/manual/reference/operator/query/where/

Here is the query to find documents from datasets collection which have 'Turnaround' on 2nd index of any sub-subdocument of 'data' sub-document:

 db.datasets.find({ $where: function () { var searchItem = 'Turnaround';  var dataObj = this.data; for (var key in dataObj) { var valueList = dataObj[key]; if (valueList.indexOf(searchItem) != -1) { return true; } } return false; } })

Please note that $where does not utilize indexes, so use it at your own risk :P

I hope it helps.

Upvotes: 1

Related Questions