Какой запрос использует меньше ресурсов в MongoDB?

#mongodb #search #lucene #aggregation-framework #mongodb-atlas-search

#mongodb #Поиск #lucene #агрегация-фреймворк #mongodb-atlas-поиск

Вопрос:

Я знакомлюсь с поиском Lucene и MongoDB Atlas, и у меня есть вопрос об эффективности запроса.

Какой из этих запросов использует меньше ресурсов?

Если есть лучшие запросы для выполнения приведенной ниже задачи, пожалуйста, дайте мне знать.

Я хочу вернуть все фильмы (sample_mflix), которые соответствуют значению заголовка. Фильмы должны быть за определенный год (не должны возвращать фильмы, не относящиеся к этому году), и я хотел бы возвращать фильмы со значениями «$ gte» для фильмов.награды. номинации и фильмы.награды.победы.

Первый запрос кажется более сложным (что, по-видимому, увеличивает использование ресурсов — сложность запроса?). Этот запрос также не возвращает значения только за этот год. Это заставляет меня думать, что, вероятно, есть лучший способ сделать это с помощью Atlas search.

Второй запрос использует $search и $match на разных этапах. Он имеет простой поиск Lucene (который может возвращать больше фильмов, чем первый запрос?), И оператор сопоставления будет фильтровать результаты. Второй запрос более точный — из моих тестов он учитывает ограничение на год. Если я применю этап ограничения, будет ли это лучшим решением?

Если бы эти запросы выполнялись по одному и тому же сценарию, какой из них был бы более эффективным и почему (прошу прощения, второй запрос отформатирован для .net driver)?

 new BsonArray
{
    new BsonDocument("$search", 
    new BsonDocument
        {
            { "index", "nostoreindex" }, 
            { "compound", 
    new BsonDocument
            {
                { "must", 
    new BsonDocument("near", 
    new BsonDocument
                    {
                        { "path", "year" }, 
                        { "origin", 2000 }, 
                        { "pivot", 1 }
                    }) }, 
                { "must", 
    new BsonDocument("text", 
    new BsonDocument
                    {
                        { "query", "poor" }, 
                        { "path", "title" }
                    }) }, 
                { "should", 
    new BsonDocument("range", 
    new BsonDocument
                    {
                        { "path", "awards.nominations" }, 
                        { "gte", 1 }
                    }) }, 
                { "should", 
    new BsonDocument("range", 
    new BsonDocument
                    {
                        { "path", "awards.wins" }, 
                        { "gte", 1 }
                    }) }
            } }
        })
}
  

против

 var searchStage =
                new BsonDocument("$search",
                    new BsonDocument
                        {
                            { "index", "nostoreindex" },
                            { "text",
                    new BsonDocument
                            {
                                { "query", title },
                                { "path", "title" }
                            } }
                        });
            var matchStage = new BsonDocument("$match",
            new BsonDocument("$and",
            new BsonArray
                    {
                new BsonDocument("year",
                new BsonDocument("$eq", year)),
                new BsonDocument("awards.nominations",
                new BsonDocument("$gte", nominations)),
                new BsonDocument("awards.wins",
                new BsonDocument("$gte", awards))
                    })
            );
  

Комментарии:

1. Протестируйте как на своем оборудовании, так и с вашими данными.

Ответ №1:

При использовании Atlas Search лучше избегать использования следующего $match фильтра после вашего $search этапа. Это связано с тем, что все данные необходимо будет искать в вашем mongod по идентификатору, что может быть довольно медленным.

Итак, как правило, вы пытаетесь сохранить свой поиск и фильтры «в Lucene», если это возможно, чтобы избежать дополнительного ввода-вывода и сравнений.

В вашем случае вы используете, near который вернет все результаты в порядке убывания от ближайшего. Вместо этого вы должны использовать range который может фильтровать эти результаты и ускорить ваш запрос.

near используется для более высокой оценки ваших результатов, если они ближе к определенному значению, которое может имитировать сортировку. Например, если вы хотите получить результаты с более высокими ‘awards.wins’, вы можете добавить near : { origin: 10000, pivot: 1} тогда, чем ближе значение к 10000 , тем выше оценка.

 new BsonArray
{
    new BsonDocument("$search", 
    new BsonDocument
        {
            { "index", "nostoreindex" }, 
            { "compound", 
    new BsonDocument
            {
                { "must", 
    new BsonDocument("range", 
    new BsonDocument
                    {
                        { "path", "year" }, 
                        { "gte", 2000 }, 
                        { "lte", 2000 }
                    }) }, 
                { "must", 
    new BsonDocument("text", 
    new BsonDocument
                    {
                        { "query", "poor" }, 
                        { "path", "title" }
                    }) }, 
                { "should", 
    new BsonDocument("range", 
    new BsonDocument
                    {
                        { "path", "awards.nominations" }, 
                        { "gte", 1 }
                    }) }, 
                { "should", 
    new BsonDocument("range", 
    new BsonDocument
                    {
                        { "path", "awards.wins" }, 
                        { "gte", 1 }
                    }) }
            } }
        })
}