Вы можете использовать GROUP_CONCAT
:
SELECT person_id, GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies GROUP BY person_id
Как сказал Людвиг в в своем комментарии, , вы можете добавить оператор DISTINCT
в избегайте дубликатов:
SELECT person_id, GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ')
FROM peoples_hobbies GROUP BY person_id
Как указано в в комментарии к , , вы также можете сортировать значения перед их использованием с помощью ORDER BY
:
SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ')
FROM peoples_hobbies GROUP BY person_id
Как сказал Даг в его комментарий, , на результат будет 1024 байта. Чтобы решить эту проблему, запустите этот запрос перед запросом:
SET group_concat_max_len = 2048
Конечно, вы можете изменить 2048
в соответствии с вашими потребностями. Чтобы вычислить и присвоить значение:
SET group_concat_max_len = CAST(
(SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ')
FROM peoples_hobbies GROUP BY person_id)
AS UNSIGNED
)
В основном при использовании мангуста документы можно получить с помощью помощников. Каждый модельный метод, который принимает условия запроса, может быть выполнен с помощью метода callback
или exec
.
callback
:
User.findOne({ name: 'daniel' }, function (err, user) {
//
});
exec
:
User
.findOne({ name: 'daniel' })
.exec(function (err, user) {
//
});
Поэтому, когда вы не проходите обратный вызов, вы можете создать запрос и в конечном итоге выполнить его.
Вы можете найти дополнительную информацию в документах mongoose ].
UPDATE
Что-то, что следует учитывать при использовании Promises в сочетании с асинхронными операциями Mongoose, заключается в том, что запросы Mongoose не являются обещаниями. Запросы возвращают thenable , но если вам нужно real Promise, вы должны использовать метод exec
. здесь .
Во время обновления я заметил, что я явно не ответил на вопрос:
Я никогда не видел этот метод в Javascript раньше? Что это делает?
blockquote>Ну, это не родной метод JavaScript, а часть API Mongoose.
exec()
вернет обещание, если обратный вызов не предоставляется. Таким образом, следующий шаблон очень удобен и универсален - он может прекрасно обрабатывать обратные вызовы или обещания:
function findAll(query, populate, cb) {
let q = Response.find(query);
if (populate && populate.length > 0) {
q = q.populate(populate);
}
// cb is optional, will return promise if cb == null
return q.lean().exec(cb);
}
Я рекомендую использовать обещания Bluebird с Mongoose, чтобы сделать это, используйте этот вызов:
const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
Даниэль ответил на это довольно красиво. Чтобы подробно описать исчерпывающий список способов создания и выполнения запросов, просмотрите следующие варианты использования:
Query Building
Mongoose не будет выполнять запрос до then
или exec
был вызван. Это очень полезно при построении сложных запросов. Некоторые примеры могут включать использование функций populate
и aggregate
.
User.find({name: 'John'}) // Will not execute
Выполнение с помощью обратного вызова
Несмотря на то, что многие из-за своего гнездования не нравятся, запросы могут выполняться посредством предоставляя необязательный обратный вызов.
User.find({name: 'John'}, (err, res) => {}) // Will execute
Тогда API как запросы Promises / A +
Mongoose предоставляют функцию then
. Это не следует путать с обычными обещаниями. Проще говоря, для спецификации Promises / A + требуется, чтобы функция then
работала так же, как и с обещаниями.
User.find({name: 'John'}).then(); // Will execute
Promise.all([User.find({name: 'John'}), User.find({name: 'Bob'})]) // Will execute all queries in parallel
Функция exec
От Mongoose docs If you need a fully-fledged promise, use the .exec() function.
User.find({name: 'John'}).exec(); // Will execute returning a promise