Подтвердить что ты не робот

Преобразование ObjectID в String в mongo Aggregation

Я сейчас в этом сценарии: У меня есть коллекция X:

{
  _id:ObjectId('56edbb4d5f084a51131dd4c6'),
  userRef:ObjectId('56edbb4d5f084a51131dd4c6'),
  serialNumber:'A123123',
  ...
}

Мне нужно собрать все документы, сгруппировав их по userRef + serialNumber, поэтому я пытаюсь использовать concat следующим образом:

$group: {
        _id: {
            '$concat': ['$userRef','-','$serialNumber']
        },
       ...

Таким образом, в основном в моем агрегации в MongoDB мне нужно сгруппировать документы путем конкатенации ObjectId и строки. Однако, кажется, что $concat принимает только строки в качестве параметров:

uncaught exception: aggregate failed: {

    "errmsg" : "exception: $concat only supports strings, not OID",
    "code" : 16702,
    "ok" : 0
}

Есть ли способ преобразовать ObjectId в String в выражении агрегации?

ИЗМЕНИТЬ

Этот question связан, но я не отвечаю своей проблеме. (Специально, потому что я не могу использовать ObjectId.toString() во время агрегации)

В действительности я не смог найти какую-либо операцию ObjectId(). toString() в документации Mongo, но мне интересно, есть ли какая-нибудь сложная вещь, которая может быть выполнена в этом случае.

4b9b3361

Ответ 1

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

В конце он выглядел примерно так:

db.collection('myCollection').mapReduce(
    function() {
        emit(
            this.userRef.str + '-' + this.serialNumber , {
                count: 1,
                whateverValue1:this.value1,
                whateverValue2:this.value2,
                ...
            }
        )
    },
    function(key, values) {
       var reduce = {}
       .... my reduce function....
        return reduce
    }, {
        query: {
            ...filters_here....
        },
        out: 'name_of_output_collection'
    }
);

Ответ 2

Теперь вы можете попробовать с агрегацией $toString которая просто преобразует ObjectId в строку

db.collection.aggregate([
    { "$addFields": {
        "userRef": { "$toString": "$userRef" }
    }},
    { "$group": {
      "_id": { "$concat": ["$userRef", "-", "$serialNumber"] }
    }}
])

Вы можете проверить вывод здесь

Ответ 3

Я думаю, вы можете попытаться разрешить его, используя массив, содержащий оба поля:

{$project:{newkey:['$userRef','$serialNumber']},{$match:{newkey:{$in:filterArray}}}}

это может соответствовать данным с обоими полями фильтра. Обратите внимание, что данные в массиве newkey должны иметь один и тот же тип данных с элементами filterArray.

Ответ 4

Вы можете использовать $substr https://docs.mongodb.com/manual/reference/operator/aggregation/substr/#exp._S_substr, чтобы передать любой объект в строку до $concat.

Это образец кода, который работает для меня.

group_id_i['_id'] = {
    '$concat' => [
        { '$substr' => [ {'$year' => '$t'}, 0, -1] }, '-',
        { '$substr' => [ {'$month' => '$t'}, 0, -1] }, '-',
        { '$substr' => [ {'$dayOfMonth' => '$t'}, 0, -1] }
    ]
} 

Где t - это поле DateTime, это агрегирование возвращает такие данные.

{
    "_id" => "28-9-2016",
    "i" => 2
}