Yashveer Singh
Yashveer Singh

Reputation: 1987

Mongodb $in query for Array not working

Below is the schema of document in mongo db

{
    "_id" : ObjectId("55d9a2f467d16f15a886a532"),
    "Author" : "RYTnirY",
    "Title" : "MZDCGMyXLV",
    "Content" : "HotEXFcyjaipabbAXAkKR",
    "Tags" : [ 
        "oHE,SJx,FMQ"
    ],
    "CreatedAtUtc" : ISODate("2015-08-23T10:39:48.766Z"),
    "Comments" : [ 
        {
            "Author" : "RWfSxDZ",
            "Content" : "TvYfJzLtIeaIdrxdsbQ",
            "CreatedAtUtc" : Date(-62135596800000)
        }, 
        {
            "Author" : "RFmUqfD",
            "Content" : "lHpUwrLnzXMSFtpGmo",
            "CreatedAtUtc" : Date(-62135596800000)
        }
    ]
}

I want to find all documents with a specific tag for example only by oHE or oHE,SJx . I am not able to find correct query .

db.poss.find({ Tags: { $in: { [ "oHE","SJx" ] } }})

Upvotes: 1

Views: 3669

Answers (3)

Sede
Sede

Reputation: 61273

The best way is using Bulk operations

var bulk = db.poss.initializeOrderedBulkOp(),
    count = 0;

db.poss.find().forEach(function(doc){ 
    var tag = doc.Tags[0].split(","); 
    bulk.find({"_id": doc._id}).updateOne({
        "$set": { "Tags": tag }
    }); 
    count++; 
    if (count % 500 == 0){
        // Execute per 500 operations and re-init
        bulk.execute();     
        bulk = db.poss.initializeOrderedBulkOp(); 
    } 
})

// Clean up queues
if ( count % 500 != 0 )
    bulk.execute()

Then your data look like this:

{
        "_id" : ObjectId("55d9a2f467d16f15a886a532"),
        "Author" : "RYTnirY",
        "Title" : "MZDCGMyXLV",
        "Content" : "HotEXFcyjaipabbAXAkKR",
        "Tags" : [
                "oHE",
                "SJx",
                "FMQ"
        ],
        "CreatedAtUtc" : ISODate("2015-08-23T10:39:48.766Z"),
        "Comments" : [
                {
                        "Author" : "RWfSxDZ",
                        "Content" : "TvYfJzLtIeaIdrxdsbQ",
                        "CreatedAtUtc" : "Sun Aug 23 2015 15:22:04 GMT+0300 (MSK)"
                },
                {
                        "Author" : "RFmUqfD",
                        "Content" : "lHpUwrLnzXMSFtpGmo",
                        "CreatedAtUtc" : "Sun Aug 23 2015 15:22:04 GMT+0300 (MSK)"
                }
        ]
}

Now your query:

db.poss.find({ "Tags": { "$in": [ "oHE","SJx" ]  }})

Upvotes: 0

Valery Viktorovsky
Valery Viktorovsky

Reputation: 6736

You stored tags as single array item ["oHE,SJx,FMQ"] instead of multiple items ["oHE", "SJx, "FMQ"] that's why query doesn't work.

You can convert tags string to array using code bellow:

var cursor = db.poss.find();
while (cursor.hasNext()) {
  var x = cursor.next();
  var tags = x['Tags'][0];
  print("Before: "+x['Tags']);
  x['Tags'] = tags.split(',');
  print("After: "+x['Tags']);
  db.poss.update({_id : x._id}, x);
}

or

db.poss.find().forEach(function (el) {
    var tags = el.Tags[0];
    el.Tags = tags.split(',');
    db.poss.save(el);
});

Upvotes: 3

Alexander Korzhykov
Alexander Korzhykov

Reputation: 1073

Firs of all - make it ["oHE", "SJx, "FMQ"] instead of ["oHE,SJx,FMQ"]. Then change your query to db.poss.find({Tags: {$in: ["oHE", "SJx"] }})

Upvotes: 0

Related Questions