1

Need help constructing this mongo query. So far I can query on the first level, but unable to do so at the next embedded level ("labels" > 2")

For example, the document structure looks like this:

> db.versions_20170420.findOne();
{
    "_id" : ObjectId("54bf146b77ac503bbf0f0130"),
    "account" : "foo",
    "labels" : {
        "1" : {
            "name" : "one",
            "color" : "color1"
        },
        "2" : {
            "name" : "two",
            "color" : "color2"
        },
        "3" : {
            "name" : "three",
            "color" : "color3"
        }
    },
    "profile" : "bar",
    "version" : NumberLong("201412192106")

This query I can filter at the first level (account, profile).

db.profile_versions_20170420.find({"account":"foo", "profile": "bar"}).pretty()

However, given this structure, I'm looking for documents where the "label" > "2". It doesn't look like "2" is a number, but a string. Is there a way to construct the mongo query to do that? Do I need to do some conversion?

1 Answer 1

1

If I correctly understand you and your data structure, "label" > "2" means that object labels must contain property labels.3, and it is easy to check with next code:

db.profile_versions_20170420.find(
    {"account": "foo", "profile": "bar", "labels.3": {$exists: true}}
).pretty();

But it doesn't mean that your object contains at least 3 properties, because it is not $size function which calculates count of elements in array, and we cannot use $size because labels is object not array. Hence in our case, we only know that labels have property 3 even it is the only one property which labels contains.

You can improve find criteria:

db.profile_versions_20170420.find({
    "account": "foo",
    "profile": "bar",
    "labels.1": {$exists: true},
    "labels.2": {$exists: true},
    "labels.3": {$exists: true}
}).pretty();

and ensure that labes contains elements 1, 2, 3, but in this case, you have to care about object structure on application level during insert/update/delete data in document.

As another option, you can update your db and add extra field labelsConut and after that you will be able to run query like this:

db.profile_versions_20170420.find(
    {"account": "foo", "profile": "bar", "labelsConut": {$gt: 2}}
).pretty();

btw, it will work faster...

Sign up to request clarification or add additional context in comments.

Comments

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.