2016-06-26 2 views
2

Учитывая сбор (#name: пользователи) Структура:Преобразовать дату ISO в формате гггг-мм-дд

{ 
"_id" : ObjectId("57653dcc533304a40ac504fc"), 
"username" : "XYZ", 
"followers" : [ 
    { 
     "count" : 31, 
     "ts" : ISODate("2016-06-17T18:30:00.996Z") 
    }, 
    { 
     "count" : 31, 
     "ts" : ISODate("2016-06-18T18:30:00.288Z") 
    } 
] 
} 

Я хочу, чтобы запросить эту коллекцию на основе поля имени пользователя и ц быть возвращено в «yyyy- мм-дд '. Ожидаемый результат:

{ 
"_id" : ObjectId("57653dcc533304a40ac504fc"), 
"username" : "XYZ", 
"followers" : [ 
    { 
     "count" : 31, 
     "date" : "2016-06-17" 
    }, 
    { 
     "count" : 31, 
     "date" : "2016-06-18" 
    } 
] 
} 

Я пытался что-то вроде этого:

db.users.aggregate([ 
{$match:{"username":"xyz"}}, 
{$project:{ "followers":{"count":1, 
     "date":"$followers.ts.toISOString().slice(0,10).replace(/-/g,'-')" 
      }} 
} 
]) 

Но это не кажется, работает. Кто-нибудь может помочь? Спасибо большое.

ответ

3

Рассмотрите управление агрегации трубопровода, который позволит вам выравнивать список данных, первый проект нового поля с помощью оператора в $dateToString, затем перегруппировать сплющенные документы, чтобы получить желаемый результат.

выше может быть показан в трех различных трубопроводов:

db.users.aggregate([ 
    { "$match": { "username": "xyz" } }, 
    { "$unwind": "$followers" }, 
    { 
     "$project": { 
      "username": 1, 
      "count": "$followers.count", 
      "date": { "$dateToString": { "format": "%Y-%m-%d", "date": "$followers.ts" } } 
     } 
    }, 
    { 
     "$group": { 
      "_id": "$_id", 
      "username": { "$first": "$username" }, 
      "followers": { "$push": { 
       "count": "$count", 
       "date": "$date" 
      }} 
     } 
    } 
]) 

С MongoDB 3.4 и новее, вы можете использовать новый $addFields шаг трубопровода вместе с $map для создания поля массива без необходимости разматывать и группировать:

db.users.aggregate([ 
    { "$match": { "username": "xyz" } },  
    { 
     "$addFields": { 
      "followers": { 
       "$map": { 
        "input": "$followers", 
        "as": "follower", 
        "in": { 
         "count": "$$follower.count", 
         "date": { 
          "$dateToString": { 
           "format": "%Y-%m-%d", 
           "date": "$$follower.ts" 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
]) 
+1

спасибо человеку. :) Это сработало отлично. – Veer

0

Лучший и простой способ сделать это - преобразовать каждый элемент в массив с помощью оператора $map. Конечно, в выражении «in» вам нужно использовать $dateToString, чтобы преобразовать «дату» в строку с помощью format specifiers.

db.coll.aggregate(
    [ 
     { "$match": { "username": "XYZ" } }, 
     { "$project": { 
      "username": 1, 
      "followers": { 
       "$map": { 
        "input": "$followers", 
        "as": "f", 
        "in": { 
         "count": "$$f.count", 
         "date": { 
          "$dateToString": { 
           "format": "%Y-%m-%d", 
           "date": "$$f.ts" 
          } 
         } 
        } 
       } 
      } 
     }} 
    ] 
) 

, который производит:

{ 
    "_id" : ObjectId("57653dcc533304a40ac504fc"), 
    "username" : "XYZ", 
    "followers" : [ 
     { 
      "count" : 31, 
      "date" : "2016-06-17" 
     }, 
     { 
      "count" : 31, 
      "date" : "2016-06-18" 
     } 
    ] 
} 
Смежные вопросы