Пн goose полнотекстовый поиск некорректно фильтруется - PullRequest
0 голосов
/ 29 апреля 2020

Итак, в основном у меня есть модель с кучей строковых полей, таких как:

const Schema: Schema = new Schema(
  {
    title: {
      type: String,
      trim: true
    },
    description: {
      type: String,
      trim: true
    },
    ...
  }
);

Schema.index({ '$**': 'text' });

export default mongoose.model('Watch', Schema);

, где я все их индексирую.

Теперь, когда я ищу, эта схема используется как ссылка на другую модель. Я выполняю поиск, подобный этому, где user является экземпляром другой модели

  const { search, limit = 5 } = req.query;
  const query = search && { match: { $text: { $search: new RegExp(search, 'i') } } };

  const { schemaRes } = await user
    .populate({
      path: 'schema',
      ...query,
      options: {
        limit
      }
    })
    .execPopulate();

, и сам поиск, кажется, работает нормально, проблема в том, что поля поиска начинают становиться более Speci c Мне кажется, что это не очень хорошо.

Пример дБ

  { title: 'Rolex', name: 'Submariner', description: 'Nice' }
  { title: 'Rolex', name: 'Air-King', description: 'Nice' }

Когда параметр поиска Rolex Я получаю оба элемента, что нормально, но когда параметр поиска становится Rolex Air-King я продолжаю получать оба предмета, что мне нехорошо, потому что я бы предпочел получить только один.

Могу ли я что-то сделать для этого?

1 Ответ

0 голосов
/ 29 апреля 2020

Возвращение обоих элементов правильное, поскольку оба элемента соответствуют параметрам поиска, но с разным показателем сходства.

Вы можете вывести показатель сходства, чтобы упростить сортировку результата.

user.aggregate([
  { $match: { $text: { $search: "Rolex Air-King" } } },
  { $set: {  score: { $meta: "textScore" } } }
])
// new RegExp("Rolex Air-King", 'i') is not necessary and even invalid,
// as $search accepts string and is already case-insensitive by default

Запрос вернет

[{
  "_id": "...",
  "title": "Rolex",
  "name": "Air-King",
  "description": "Nice",
  "score": 2.6
},
{
  "_id": "....",
  "title": "Rolex",
  "name": "Submariner",
  "description": "Nice",
  "score": 1.1
}]

Поскольку второй элемент результата соответствует вашему поисковому запросу (даже частично), MongoDB возвращает его.

Вы можете использовать счет для сортировки элементов. Но определить правильное пороговое значение для фильтрации результата сложно, так как оценка зависит также от количества слов.

С другой стороны: вы можете назначать разным весам поля, если они не одинаково важны https://docs.mongodb.com/manual/tutorial/control-results-of-text-search/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...