1

I'm having some subdocument in MongoDB that occasionally include different types - string, another subdocument, another nested subdocument etc. I'm trying to build a query that will search within this subdocument content regardless of it's type.

Given the following documents:

{ name: "test1", content: "test contents"}
{ name: "test2", content: {family: "tests family content", last: "another test content"} }
{ name: "test3", content: {subdocument: {family: "super family contents", last: "last test content"} } }

I want to use a query that will search within all strings within all documents and subdocuments. Already tried the following query, but it returns only the most nested level of subdocument - content.subdocument.family:

{ $or: [
    {"content": {'$regex': '.*conten.*', '$options': 'i'}},
    {"content.family": {'$regex': '.*conten.*', '$options': 'i'}},
    {"content.last": {'$regex': '.*conten.*', '$options': 'i'}},
    {"content.subdocument.family": {'$regex': '.*conten.*', '$options': 'i'}},
    {"content.subdocument.last": {'$regex': '.*conten.*', '$options': 'i'}}
]}

Is it possible to create one query that will iterate over all nested strings\deeps at once?

Do5
  • 13
  • 3
  • It is very unclear what you are asking. Please read [how to ask](http://stackoverflow.com/help/how-to-ask) a good question and use the [edit link](http://stackoverflow.com/posts/32521668/edit) to improve your question. – styvane Sep 11 '15 at 14:44
  • Tried to edit the title, intro and the question, hope it's better now... – Do5 Sep 12 '15 at 19:40
  • BTW, in the meanwhile, as a workaround I'm asking the user what deep he wants to search. Otherwise it is also possible to create 3 different queries and then check the answers later – Do5 Sep 12 '15 at 19:43

1 Answers1

0

Here you are missing syntax of $or in $regex. You should use $or like following:

db.collection.find({
    $or: [{
    "content": {
        '$regex': '.*conten.*',
        '$options': 'i'
    }
    }, {
    "content.family": {
        '$regex': '.*conten.*',
        '$options': 'i'
    }
    }, {
    "content.last": {
        '$regex': '.*conten.*',
        '$options': 'i'
    }
    }, {
    "content.subdocument.family": {
        '$regex': '.*conten.*',
        '$options': 'i'
    }
    }, {
    "content.subdocument.last": {
        '$regex': '.*conten.*',
        '$options': 'i'
    }
    }]
})

Edit:

Above query gives following result:

[{
    "_id": ObjectId("55f41b6aef4766c946112a2d"),
    "name": "test1",
    "content": "test contents"
}, {
    "_id": ObjectId("55f41b6aef4766c946112a2e"),
    "name": "test2",
    "content": {
    "family": "tests family content",
    "last": "another test content"
    }
}, {
    "_id": ObjectId("55f41b6aef4766c946112a2f"),
    "name": "test3",
    "content": {
    "subdocument": {
        "family": "super family contents",
        "last": "last test content"
    }
    }
}]
Vishwas
  • 6,967
  • 5
  • 42
  • 69
  • You are right, but that was just a typo in writing the question, unfortunately it doesn't solve the problem. – Do5 Sep 12 '15 at 19:35
  • @Do5 What exact output do you want? – Vishwas Sep 13 '15 at 12:46
  • I want to be able to search a string in all possible fields within "content". The output structure is less relevant, it might be the whole document, only the relevant field or only the relevant sub-document, that doesn't matter – Do5 Sep 13 '15 at 13:25
  • The output you get is great, but for some reason I don't get it, I get only the third one - test3 – Do5 Sep 13 '15 at 14:30
  • This is a really sad story for me... I checked again with this specific documents and query. And WOW! it did return all records as you wrote! Then, I went back to my application to discover it was really working all along I just had a lot of documents and a very long output, to watch it, I was supposed to type "it"... – Do5 Sep 13 '15 at 14:46