RethinkDB группирует и определяет выходные данные

У меня есть таблица, содержащая документы, похожие на это:

{
"title": "title 2",
"content": "This far, no further!",
"category": "Fiction"
}

Это запрос, который я использую:

r.table('posts').group('title').map(lambda item:
    {'items': item['title']}
).run())

Это результат:

{
  "title 1" : [
    {
      "items" : "title 1"
    },
    {
      "items" : "title 1"
    }
  ],
  "Title 2" : [
    {
      "items" : "Title 2"
    },
    {
      "items" : "Title 2"
    },
    {
      "items" : "Title 2"
    },
    {
      "items" : "Title 2"
    }
  ],
  "title 3" : [
    {
      "items" : "title 3"
    }
  ]
}

Однако я хотел бы получить структуру вывода, которая выглядит следующим образом:

{
  "Title 1" : {
    "item_count" : 3,
    "items" : [
      {
        "items" : "title 1"
      },
      {
        "items" : "title 1"
      },
      {
        "items" : "title 1"
      }
    ]
  },
  "Title 2" : {
    "item_count" : 2,
    "items" : [
      {
        "items" : "title 2"
      },
      {
        "items" : "title 2"
      }
    ]
  },
  "Title 3" : {
    "item_count" : 1,
    "items" : [
      {
        "items" : "title 3"
      }
    ]
  }
}

Как мне создать запрос, чтобы получить этот результат.


person user1513388    schedule 13.06.2015    source источник


Ответы (1)


Для этого вам нужно map выполнить запрос после выполнения в нем ungroup.

Во-первых, вывод вашего первого запроса выглядит некорректно. RethinkDB не вернет объект/словарь после операции map, он вернет массив. Результат, который я получил из вашего запроса, был следующим:

[
  {
    "group":  "title 1" ,
    "reduction": [
      {
        "items":  "title 1"
      } ,
      {
        "items":  "title 1"
      }
    ]
  } ,
  {
    "group":  "title 2" ,
    "reduction": [
      {
        "items":  "title 2"
      } ,
      {
        "items":  "title 2"
      }
    ]
  } ,
  ...
]

Если вам нужно свойство с именем items вместе с подсчетом количества элементов в этом свойстве items, вы можете сделать следующее:

// THIS IS JAVASCRIPT
r.table('posts')
 .group('title')
 .map(function (item) {
    return {
      items: item('title')
    }
 })
 .ungroup()
 .map(function (row) { 
    return {
      'title': row('group'),
      'items': row('reduction'),
      'count': row('reduction').count()
    }
  })

Результат этого запроса будет следующим:

[
  {
    "count": 2 ,
    "items": [
      {
        "items":  "title 1"
      },
      {
        "items":  "title 1"
      }
    ],
    "title":  "title 1"
    },
  {
    "count": 2 ,
    "items": [
      {
        "items":  "title 2"
      } ,
      {
        "items":  "title 2"
      }
    ] ,
    "title":  "title 2"
  },
  ...
]

Если вы хотите затем превратить этот запрос в объект/словарь, чтобы вы могли вызывать сообщение по его заголовку, вы можете превратить этот массив сообщений в объект, используя r.object вместе с r.args. Полный запрос будет выглядеть так:

// THIS IS JAVASCRIPT
r.table('posts')
 .group('title')
 .map(function (item) {
    return {
      items: item('title')
    }
 })
 .ungroup()
 .map(function (row) {
    return {
      'title': row('group'),
      'items': row('reduction'),
      'count': row('reduction').count()
    }
  })
  .do(function (rows) {
    return r.object(r.args(rows.concatMap(function (row) {
      return [row('title'), row];
    })));
  })

Результат этого запроса будет примерно таким:

{
  "title 1": {
    "count": 2 ,
    "items": [
      {
        "items":  "title 1"
      } ,
      {
        "items":  "title 1"
      }
    ] ,
    "title":  "title 1"
  } ,
  "title 2": {
    "count": 2 ,
    "items": [
      {
        "items":  "title 2"
      } ,
      {
        "items":  "title 2"
      }
    ] ,
    "title":  "title 2"
  } ,
  ...
}
person Jorge Silva    schedule 15.06.2015