Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как правильно отфильтровать данные в MongoDB? (https://javascript.ru/forum/dom-window/78464-kak-pravilno-otfiltrovat-dannye-v-mongodb.html)

darktowerk56c 18.09.2019 07:50

Как правильно отфильтровать данные в MongoDB?
 
Всем привет, подскажите, пожалуйста, как правильно сделать следующую фильтрацию в MongoDB?
У меня есть три документа.
{
    "_id": {
        "$oid": "5d7f70d46b647c1a74d9b8aa"
    },
    "firstName": "user",
    "lastName": "one",
    "phoneNumber": "+7 (111) 111-11-11",
    "city": "Москва",
    "userId": {
        "$oid": "5d5ea4596886b1107c2be849"
    },
    "__v": 0
}


{
    "_id": {
        "$oid": "5d7f70d46b647c1a74d9b8aa"
    },
    "firstName": "user",
    "lastName": "two",
    "phoneNumber": "+7 (222) 222-22-22",
    "city": "Сочи",
    "userId": {
        "$oid": "5d5ea4596886b1107c2be849"
    },
    "__v": 0
}


{
    "_id": {
        "$oid": "5d7f70d46b647c1a74d9b8aa"
    },
    "firstName": "user",
    "lastName": "two",
    "phoneNumber": "+7 (333) 333-33-33",
    "city": "Москва",
    "userId": {
        "$oid": "5d5ea4596886b1107c2be849"
    },
    "__v": 0
}

На вход у меня приходит, например такой массив:
['ne', 'чи']

Ожидается результат поиска по всем документам и следующим полям в этих документах: ['firstName', 'lastName', 'phoneNumber', 'city']
Очевидно, в дальнейшем эти поля могут изменяться: либо поиск только по 'city', либо же только по 'firstName' и 'lastName'
Результат:
{
    "_id": {
        "$oid": "5d7f70d46b647c1a74d9b8aa"
    },
    "firstName": "user",
    "lastName": "one",
    "phoneNumber": "+7 (111) 111-11-11",
    "city": "Москва",
    "userId": {
        "$oid": "5d5ea4596886b1107c2be849"
    },
    "__v": 0
}


{
    "_id": {
        "$oid": "5d7f70d46b647c1a74d9b8aa"
    },
    "firstName": "user",
    "lastName": "two",
    "phoneNumber": "+7 (222) 222-22-22",
    "city": "Сочи",
    "userId": {
        "$oid": "5d5ea4596886b1107c2be849"
    },
    "__v": 0
}

Модель выглядит следующим образом:
const { Schema, model } = require('mongoose')

const bookSchema = new Schema({
  firstName: {
    type: String,
    required: true
  },
  lastName: {
    type: String,
    required: true
  },
  city: {
    type: String,
    required: true
  },
  phoneNumber: {
    type: String,
    required: true
  },
  userId: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  }
})

module.exports = model('Book', bookSchema)

контроллер:
exports.searchBook = (req, res, next) => {
  console.log(req.body) // ['ne', 'чи']

  // just an example of a simple search
  // Book.find({
  //   lastName: 'one'
  // })
  //   .then(book => {
  //     console.log('book', book)
  //   })
  //   .catch(err => {
  //     if (!err.statusCode) {
  //       err.statusCode = 500
  //     }
  //     next(err)
  //   })
}

Моя попытка реализовать эту задачу. Проблема в том, что корректно будет искать, только если на вход будет приходить слово без пробелов: 'со'.
Задача же работать с чем-то вроде этого 'со tw'
exports.searchBook = (req, res, next) => {
  console.log(req.body) // ['ne', 'чи']

  const term = req.body.join(' ')
  console.log(term)

  Book.aggregate([
    {
      $match: {
        $or: [
          {
            firstName: {
              '$regex': term, //  'чи'
              '$options': 'i'
            }
          },
          {
            lastName: {
              '$regex': term,
              '$options': 'i'
            }
          },
          {
            city: {
              '$regex': term,
              '$options': 'i'
            }
          },
          {
            phoneNumber: {
              '$regex': term,
              '$options': 'i'
            }
          }
        ]
      }
    }
  ])
    .then(book => {
      console.log('book', book)
    })
    .catch(err => {
      if (!err.statusCode) {
        err.statusCode = 500
      }
      next(err)
    })
}


Часовой пояс GMT +3, время: 02:36.