2

есть агрегация трубопровода:

db.getCollection('yourCollection').aggregate(
    { 
     $unwind: { 
      path: "$dates", 
      includeArrayIndex: "idx" 
     } 
    }, 
    { 
     $project: { 
      _id: 0, 
      dates: 1, 
      numbers: { $arrayElemAt: ["$numbers", "$idx"] }, 
      goals: { $arrayElemAt: ["$goals", "$idx"] }, 
      durations: { $arrayElemAt: ["$durations", "$idx"] } 
     } 
    } 
) 

, которые выполняют на следующих данных (образцы документов):

{ 
    "_id" : ObjectId("52d017d4b60fb046cdaf4851"), 
    "dates" : [ 
     1399518702000, 
     1399126333000, 
     1399209192000, 
     1399027545000 
    ], 
    "dress_number" : "4", 
    "name" : "J. Evans", 
    "numbers" : [ 
     "5982", 
     "5983", 
     "5984", 
     "5985" 
    ], 
    "goals": [ 
     "1", 
     "0", 
     "4", 
     "2" 
    ], 
    "durations": [ 
     "78", 
     "45", 
     "90", 
     "90" 
    ] 
} 

{ 
    "_id" : ObjectId("57e250c1b60fb0213d06737c"), 
    "dates" : [ 
     "1399027545000", 
     "1399101432000", 
     "1399026850000", 
     "1399904504000" 
    ], 
    "dress_number" : "6", 
    "name" : K. Mitnick, 
    "numbers" : [ 
     "0982", 
     "0981", 
     "0958", 
     "0982" 
    ], 
    "durations" : [ 
     98, 
     110, 
     66, 
     92 
    ], 
    "goals" : [ 
     "2", 
     "3", 
     "0", 
     "1" 
    ] 
} 

Запрос работает хорошо, но есть дублирующие записи, поэтому я пытаюсь использовать оператор , чтобы избежать дублирования:

db.getCollection('yourCollection').aggregate(
     { 
      $match: { 
       "number": number 
      } 
     }, 
     { 
      $unwind: { 
       path: "$dates", 
       includeArrayIndex: "idx" 
      } 
     }, 
     $group: { 
        _id: '$_id', 
        dates: { $addToSet: '$dates' } 
     }, 
     { 
      $project: { 
       _id: 0, 
       dates: 1, 
       numbers: { $arrayElemAt: ["$numbers", "$idx"] }, 
       goals: { $arrayElemAt: ["$goals", "$idx"] }, 
       durations: { $arrayElemAt: ["$durations", "$idx"] } 
      } 
     } 
    ) 

, но я получил только даты (другие поля являются null)

{ dates: 
    [ '1399026850000', 
     '1399101432000', 
     '1399027545000', 
     '1399904504000', 
     '1399024474000', 
     '1399126333000' ], 
    numbers: null, 
    goals: null, 
    durations: null }, 
    { dates: 
    [ '1399027545000', 
     '1399024474000', 
     '1399518702000', 
     '1399126333000', 
     '1399209192000', 
     '1399356651000' ], 
    numbers: null, 
    goals: null, 
    conversation_durations: null }, 
    { dates: 
    [ '1399026850000', 
     '1399101432000', 
     '1399027545000', 
     '1399904504000', 
     '1399024474000' ], 
    numbers: null, 
    goals: null, 
    durations: null } 

Кто-нибудь знает, где проблема?

+1

Когда вы делаете $ группу , вы по существу исключаете все другие переменные. После этого вы не сможете повторно спроектировать их обратно. Если все, что вы пытаетесь сделать, это удалить дубликаты из ваших массивов, лучше всего либо сделать это в коде javascript/client, либо использовать сокращение карты. См. Здесь: http://stackoverflow.com/questions/9862255/how-to-remove-duplicate-entries-from-an-array Вы также можете изменить этап конвейера $ group, чтобы добавить туда другие поля (см. хридам). – dyouberg

ответ

5

Вам необходимо включить поля внутри $group трубопровода с помощью оператора $first следующим образом:

db.getCollection('yourCollection').aggregate([ 
    { "$unwind": "$dates" }, 
    { 
     "$group": { 
      "_id": "$_id", 
      "dates": { "$addToSet": "$dates" }, 
      "numbers": { "$first": "$numbers" }, 
      "goals": { "$first": "$goals" }, 
      "durations": { "$first": "$durations" } 
     } 
    }, 
    { "$unwind": { 
      "path": "$dates", 
      "includeArrayIndex": "idx" 
    } }, 
    { 
     "$project": { 
      "_id": 0, 
      "dates": 1, 
      "numbers": { "$arrayElemAt": ["$numbers", "$idx"] }, 
      "goals": { "$arrayElemAt": ["$goals", "$idx"] }, 
      "durations": { "$arrayElemAt": ["$durations", "$idx"] } 
     } 
    } 
]) 

или с помощью $setUnion для устранения дубликатов, как:

db.getCollection('yourCollection').aggregate([ 
    { 
     "$project": { 
      "_id": 0, 
      "dates": { "$setUnion": ["$dates", "$dates"] }, 
      "numbers": 1, 
      "goals": 1, 
      "durations": 1 
     } 
    } 
    { "$unwind": { 
      "path": "$dates", 
      "includeArrayIndex": "idx" 
    } }, 
    { 
     "$project": { 
      "_id": 0, 
      "dates": 1, 
      "dateIndex": "$idx", 
      "numbers": { "$arrayElemAt": ["$numbers", "$idx"] }, 
      "goals": { "$arrayElemAt": ["$goals", "$idx"] }, 
      "durations": { "$arrayElemAt": ["$durations", "$idx"] } 
     } 
    } 
]) 
+0

Спасибо, я пробовал с обоими решениями, но есть еще дубликаты:/ – corry

+0

Можете ли вы обновить свой вопрос с помощью образцов документов, которые производят дубликаты, а также показывая ожидаемый результат с этими документами? – chridam

+0

Пожалуйста, взгляните на вопрос http://stackoverflow.com/questions/39426022/mongodb-show-children-items-in-one-to-many-relationship/39426859#39426859 – corry

Смежные вопросы