Как проверить все коллекции в базе данных MongoDB для определенного ключевого слова? - PullRequest
2 голосов
/ 31 октября 2019

В настоящее время я работаю над проектом NodeJS с использованием запросов Mongoose.

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

Вот так выглядит моя коллекция:

Книги:

{
    "book_id": "ab12nld”,
    "book_version": "0”,
    "author": “Sam”,
    “name”: “Sample Book”,
    “comments”: “Done”
  },
  {
    "book_id": "a5g2nld”,
    "book_version": "1",
    "author": "Martin",
    "name": "Sample Book",
    “comments”: “In Progress”
  }

Автомобили:

{
    "car_id": "nlp240n”,
    "car_model": "3”,
    "brand": “Hyundai”,
    “name”: “Verna”,
    “color”: “Blue”
  },
  {
    "car_id": "cak201n”,
    "car_model": "1”,
    "brand": “Tata”,
    “name”: “Indica”,
    “color”: “Black”
  }

Телефоны:

{
    "phone_id": "n0830bo”,
    "brand": “OnePlus”,
    “name”: “7 Pro”,
    “color”: “Red”
  },
  {
    "phone_id": "bh97b01”,
    "brand": “IPhone”,
    “name”: “11 Pro”,
    “color”: “Black”
  }

Я получу query_string, который будет найден в этой коллекции, и если найдется подходящийрезультат, я должен получить все связанные значения.

Пример:

Если query_string равен Martin, я должен получить соответствующий результат из коллекции Книги, так как присутствует Martinтолько там:

 {
    "book_id": "a5g2nld”,
    "book_version": "1",
    "author": "Martin",
    "name": "Sample Book",
    “comments”: “In Progress”
  }

Если query_string равно Black, я должен получить соответствующий результат из коллекций автомобилей и телефонов, так как оба имеют значение Black:

{
    "car_id": "cak201n”,
    "car_model": "1”,
    "brand": “Tata”,
    “name”: “Indica”,
    “color”: “Black”
  },
{
    "phone_id": "bh97b01”,
    "brand": “IPhone”,
    “name”: “11 Pro”,
    “color”: “Black”
  }

Это кажется хитрым, и я не знаю, как двигаться дальше. Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 31 октября 2019

В вашем случае вы можете сделать это так:

var searchValue = "Martin";
// FOR EACH COLLECTION IN MONGODB...
// HERE YOU COULD ITERAVE OVER AN ARRAY OF COLLECTIONS NAMES...
// var collections = ["Books", "Cars", "Phones"];
// collections.forEach(
db.getCollectionNames().forEach(
    function(collectionName) {
        // GETTING THE FIELD NAMES FOR THE COLLECTION...
        // FOR COLLECTIONS WITH MANY DOCUMENTS IT MAY BE MORE INTERESTING TO GET THE FIELD NAMES ELSEWHERE INSTEAD OF MONGODB...
        db.getCollection(collectionName).aggregate([
          {"$project":{"arrayOfKeyValue":{"$objectToArray":"$$ROOT"}}},
          {"$unwind":"$arrayOfKeyValue"},
          {"$group":{"_id":null,"allFields":{"$addToSet":"$arrayOfKeyValue.k"}}},
          {"$project":{"collectionName": collectionName, "fieldNames": "$allFields"}}
        ]).forEach(
            function(collectionWithFieldNames) {  
                // FOR EACH FIELD NAME OF THE COLLECTION...
                collectionWithFieldNames.fieldNames.forEach(
                    function(fieldName) {
                        var name = fieldName;
                        var value = searchValue;
                        var query = {};
                        query[name] = value;

                        // QUERY THE COLLECTION SEARCHING THE SEARCH VALUE ON THE FIELD IN THE COLLECTION...
                        db.getCollection(collectionName).find(query).forEach(
                            function(result) {
                                // PRINT THE RESULT IF EXISTS...
                                // HERE YOU CAN DO EVERYTHING WITH THE RESULT...
                                print(JSON.stringify(result));
                            }
                        );
                    }
                );
            }
        )
    }
);
1 голос
/ 31 октября 2019

Вот несколько вариантов. Они используют базовые запросы и JavaScript с различными уровнями сложности:


ОПЦИЯ № 1:

Запрос по всем полям, которые вы хотите найти для каждой коллекции:

var booksFound = db.books.find( { $or [ { author: <querystring>} , { name: <querystring> } ]  } ).toArray()
var carsFound = db.cars.find( { $or [ { brand: <querystring> }, { name: <querystring> }, { color: <querystring> } ] } ).toArray()
var phonesFound = db.phones.find( { $or [ { brand: <querystring> }, { name: <querystring> }, { color: <querystring> } ] } ).toArray()

Объедините три массива результатов , используя метод JavaScript Arrays#concat, чтобы получить результат:

var resultArray = booksFound.concat(carsFound).concat(phonesFound);


Индексы и сопоставление: Обратите внимание, что для более быстрого поиска необходимо создать индексы для соответствующих полей в каждой коллекции. Вы также можете добавить нечувствительный к регистру параметр (для поиска без учета регистра) к индексу, используя collation : { collation: { locale: 'en', strength: 2 } }. См. Примечание по регистрам без учета регистра .



ОПЦИЯ № 2:

Создать новые ключевые слова поле, и это будет массив значений из полей, по которым вы хотите искать. Вы можете назвать поле как «ключевые слова» или «поисковые слова».

Например, документ коллекции cars с car_id: "nlp240n", поле ключевых слов может иметь значение keywords: [ "Hyundai", "Verna", "Blue"]

Вам нужно создать индекс для этого поля массива для более быстрого запроса. Индексы массивов называются многоключевыми индексами. Вы также можете добавить в индекс опцию без учета регистра , используя параметры сортировки. См. OPTION # 1 для получения более подробной информации о сопоставлении .

ПРИМЕЧАНИЕ. Поле ключевых слов и индексы необходимо создать для трех коллекций.

Выполните три запроса и получите результаты каждого запроса в виде массива:

var booksFound = db.books.find( { keywords: <querystring> } ).toArray();
var carsFound = db.cars.find( { keywords: <querystring> } ).toArray();
var phonesFound = db.phones.find( { keywords: <querystring> } ).toArray();

Объедините три массива , используя метод JavaScript Arrays#concat, чтобы получить результат:

var resultArray = booksFound.concat(carsFound).concat(phonesFound);


Как создать данные поля ключевых слов?

Каждый раз, когда документ вставляется, обновляется или удаляется ( и , если какие-либо поля, к которым мы обращаемся), из коллекции, массив ключевых слов необходимо соответствующим образом обновлять. При вставке добавьте значение в массив, при обновлении измените значение в массиве и при удалении удалите значение в массиве

См. Это для получения дополнительной информации: Операторы обновления массива .

...