Пн goose - сортировка зависит от логического свойства - PullRequest
4 голосов
/ 27 февраля 2020

У меня есть запрос mon goose find, и у меня есть первая схема mon goose, которая содержит это (клиент):

client: { type: ObjectId, ref: 'Client' },

И у меня есть схема клиента:

new mongoose.Schema({
  firstName: String,
  lastName: String,
  company: String,
  companyAsPrimaryName: Boolean,
})

Я хочу сделать запрос на поиск в первой схеме, зависит от логического свойства свойства companyAsPrimaryName клиента. Если это неверно: я хочу отсортировать по firstName + lastName, а если это правда, я хочу отсортировать по компании.

Я понятия не имею, как это сделать, я уже проверил ответ и ничего не нашел.

Спасибо за помощь

1 Ответ

1 голос
/ 27 февраля 2020

Что вы можете сделать, это использовать aggregate с $addFields и $cond, чтобы создать поле с именем, по которому вы хотите отсортировать, а затем отсортировать по этому полю. Следующий фрагмент будет получать каждые Foo и сортировать их по названию компании или по имени + фамилии, если companyAsPrimaryName равно false.

  const data = await Foo.aggregate([
  {
    // basically .populate('client') in our case
    $lookup: {
      from: 'clients',
      localField: 'client',
      foreignField: '_id',
      as: 'client'
    }
  },
  {
    // deconstruct the client array into one object
    $unwind: '$client'
  },
  {
    // add a computed field for sorting
    $addFields: {
      sortName: {
        $cond: {
          if: {
            $eq: ['$client.companyAsPrimaryName', true]
          },
          then: '$client.company',
          else: {
            $concat: ['$client.firstName', '$client.lastName']
          }
        }
      }
    }
  },
  {
    $sort: {
      sortName: 1
    }
  }
])
console.log(data)

Здесь Foo - это модель, содержащая client как поле. Обратите внимание, что это будет включать это поле в результат. Если вы хотите пропустить некоторые поля, вы можете добавить стадию $project, чтобы выбрать поля.

Вот фрагмент кода, который я использовал для локального тестирования:

const mongoose = require('mongoose')

const Client = mongoose.model('Client', {
  firstName: String,
  lastName: String,
  company: String,
  companyAsPrimaryName: Boolean
})

const Foo = mongoose.model('Foo', {
  name: String,
  client: { type: mongoose.Types.ObjectId, ref: 'Client' }
})

// Call this in `start()` to populate some sample data
const create = async () => {
  const client1 = await new Client({
    firstName: 'Alpha',
    lastName: 'Alphaname',
    company: 'Alphabet',
    companyAsPrimaryName: true
  }).save()
  const client2 = await new Client({
    firstName: 'John',
    lastName: 'Wayne',
    company: 'Google',
    companyAsPrimaryName: true
  }).save()
  const client3 = await new Client({
    firstName: 'Bravo',
    lastName: 'Bretty',
    company: 'Zulu Solutions',
    companyAsPrimaryName: false
  }).save()

  await new Foo({
    name: 'Toaster',
    client: client1
  }).save()
  await new Foo({
    name: 'Lunchbox',
    client: client1
  }).save()
  await new Foo({
    name: 'Treadmill',
    client: client1
  }).save()

  await new Foo({
    name: 'Tapas',
    client: client2
  }).save()
  await new Foo({
    name: 'Ananas',
    client: client2
  }).save()
  await new Foo({
    name: 'Zapiers',
    client: client2
  }).save()

  await new Foo({
    name: 'Brets',
    client: client3
  }).save()
  await new Foo({
    name: 'Xrats',
    client: client3
  }).save()
  await new Foo({
    name: 'Abins',
    client: client3
  }).save()
}

const start = async () => {
  await mongoose.connect('mongodb+srv://CONNECTION STRING HERE', {
    useNewUrlParser: true,
    useUnifiedTopology: true
  })

  const data = await Foo.aggregate([
    {
      // basically .populate('client') in our case
      $lookup: {
        from: 'clients',
        localField: 'client',
        foreignField: '_id',
        as: 'client'
      }
    },
    {
      // deconstruct the client array into one object
      $unwind: '$client'
    },
    {
      // add a computed field for sorting
      $addFields: {
        sortName: {
          $cond: {
            if: {
              $eq: ['$client.companyAsPrimaryName', true]
            },
            then: '$client.company',
            else: {
              $concat: ['$client.firstName', '$client.lastName']
            }
          }
        }
      }
    },
    {
      $sort: {
        sortName: 1
      }
    }
  ])
  console.log(data)
}

start().then(() => {
  console.log('ready')
  mongoose.disconnect()
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...