Как я могу сделать матч после раскрутки второго уровня в mongodb? - PullRequest
0 голосов
/ 15 мая 2018

Я работаю над программным обеспечением, которое использует MongoDB в качестве базы данных. У меня есть такая коллекция (это всего лишь один документ)

{
    "_id" : ObjectId("5aef51e0af42ea1b70d0c4dc"),    
    "EndpointId" : "89799bcc-e86f-4c8a-b340-8b5ed53caf83",    
    "DateTime" : ISODate("2018-05-06T19:05:04.574Z"),
    "Url" : "test",
    "Tags" : [ 
        {
            "Uid" : "E2:02:00:18:DA:40",
            "Type" : 1,
            "DateTime" : ISODate("2018-05-06T19:05:04.574Z"),
            "Sensors" : [ 
                {
                    "Type" : 1,
                    "Value" : NumberDecimal("-98")
                }, 
                {
                    "Type" : 2,
                    "Value" : NumberDecimal("-65")
                }
            ]
        }, 
        {
            "Uid" : "12:3B:6A:1A:B7:F9",
            "Type" : 1,
            "DateTime" : ISODate("2018-05-06T19:05:04.574Z"),
            "Sensors" : [ 
                {
                    "Type" : 1,
                    "Value" : NumberDecimal("-95")
                }, 
                {
                    "Type" : 2,
                    "Value" : NumberDecimal("-59")
                }, 
                {
                    "Type" : 3,
                    "Value" : NumberDecimal("12.939770381907275")
                }
            ]
        }
    ]
}    

и я хочу выполнить этот запрос к нему.

db.myCollection.aggregate([{ "$unwind" : "$Tags" },
{"$match" : { "$and" : [{ "Tags.DateTime" : { "$gte" : ISODate("2018-05-06T19:05:02Z"), "$lte" : ISODate("2018-05-06T19:05:09Z") } }, 
                { "Tags.Uid" : { "$in" : ["C1:3D:CA:D4:45:11"] } }] } },
{ "$unwind" : "$Tags.Sensors" }, { "$match" : { "$Tags.Sensors.Type" : { "$in" : [1,2] } } },
{ "$project" : { "_id" : 0, "EndpointId" : "$EndpointId", "TagId" : "$Tags.Uid", "Url" : "$Url", "TagType" : "$Tags.Type", 
    "Date" : "$Tags.DateTime", "SensorType" : "$Tags.Sensors.Type", "Value" : "$Tags.Sensors.Value" } }
])

проблема в том, что второе совпадение (которое проверяет $Tags.Sensors.Type) не работает и не влияет на результат запроса. Как я могу решить это? Если это не правильный путь, как правильно выполнять эти условия?

1 Ответ

0 голосов
/ 15 мая 2018

Этап $match принимает имена полей без начального знака $.Вы сделали это правильно на первом этапе $match, но на втором вы пишете $Tags.Sensors.Type.Простое удаление начального знака $ должно заставить ваш запрос работать.

Имейте в виду, все это может быть немного упрощено (и некоторое украшение тоже не повредит):

  1. Вам не нужно использовать $and в вашем примере, поскольку это предполагается по умолчанию, если в фильтре указано более одного критерия.

  2. $in, который вы используете для фильтра Tags.Sensors.Type, может быть простым оператором равенства :, если в списке допустимых значений нет более одного элемента.

  3. В $project stage, вместо (своего рода) дублирования идентичных имен полей вы можете использовать синтаксис <field>: 1, если только порядок полей не имеет значения.

Таким образом, окончательный запрос будет выглядеть примерно так.

db.myCollection.aggregate([
{
    "$unwind" : "$Tags"
},
{
    "$match" : {
        "Tags.DateTime" : { "$gte" : ISODate("2018-05-06T19:05:02Z"), "$lte" : ISODate("2018-05-06T19:05:09Z") },
        "Tags.Uid" : { "$in" : ["C1:3D:CA:D4:45:11"] }
    }
}, {
    "$unwind" : "$Tags.Sensors"
}, { 
    "$match" : {
        "Tags.Sensors.Type" : { "$in" : [1,2] } 
    }
},
{
    "$project" : { 
        "_id" : 0,
        "EndpointId" : 1, 
        "TagId" : "$Tags.Uid",
        "Url" : 1,
        "TagType" : "$Tags.Type", 
        "Date" : "$Tags.DateTime", 
        "SensorType" : "$Tags.Sensors.Type", 
        "Value" : "$Tags.Sensors.Value" 
    }
}])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...