Запрос на длину строки поля в документе [Meteor + MongoDB] [дубликат]

Вы можете использовать эту пользовательскую библиотеку (написанную с помощью Promise) для выполнения удаленного вызова.

function $http(apiConfig) {
    return new Promise(function (resolve, reject) {
        var client = new XMLHttpRequest();
        client.open(apiConfig.method, apiConfig.url);
        client.send();
        client.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                // Performs the function "resolve" when this.status is equal to 2xx.
                // Your logic here.
                resolve(this.response);
            }
            else {
                // Performs the function "reject" when this.status is different than 2xx.
                reject(this.statusText);
            }
        };
        client.onerror = function () {
            reject(this.statusText);
        };
    });
}

Пример простого использования:

$http({
    method: 'get',
    url: 'google.com'
}).then(function(response) {
    console.log(response);
}, function(error) {
    console.log(error)
});
41
задан chridam 11 April 2015 в 12:32
поделиться

3 ответа

Для MongoDB 3.6 и новее:

Оператор $expr позволяет использовать выражения агрегации в языке запросов, таким образом вы можете использовать использование $strLenCP , чтобы проверить длину строки следующим образом:

db.usercollection.find({ 
    "name": { "$exists": true },
    "$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] } 
})

Для MongoDB 3.4 и новее:

Вы также можете использовать структуру агрегации с оператором конвейера $redact , который позволяет выполнить логическое условие с помощью оператора $cond и использует специальные операции $$KEEP «сохранить» документ, где логическое условие истинно, или $$PRUNE «удалить» документ, в котором условие было ложным.

Эта операция аналогична наличию $project , который выбирает поля в коллекции и создает новое поле, которое содержит результат из запроса логического условия, а затем следующий $match , за исключением того, что $redact использует более эффективный один этап конвейера.

Что касается логического состояния, существуют операторы агрегирования строк , которые вы можете использовать для оператора $strLenCP для проверки длины строки. Если длина $gt имеет указанное значение, то это истинное совпадение, и документ «сохраняется». В противном случае он «обрезается» и отбрасывается.


Рассмотрите следующую операцию агрегации, которая демонстрирует приведенную выше концепцию:

db.usercollection.aggregate([
    { "$match": { "name": { "$exists": true } } },
    {
        "$redact": {
            "$cond": [
                { "$gt": [ { "$strLenCP": "$name" }, 40] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    },
    { "$limit": 2 }
])

Если вы используете $where , попробуйте свой запрос без прилагаемых скобок:

db.usercollection.find({$where: "this.name.length > 40"}).limit(2);

. Лучшим запросом было бы проверить существование поля и затем проверить длину:

db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2); 

или:

db.usercollection.find({name: {$exists: true}, $where: "this.name.length > 
40"}).limit(2); 

MongoDB оценивает операции запроса $where до $where и запроса $where операторы могут использовать индекс. Более высокая производительность - сохранить длину строки в качестве другого поля, а затем вы можете индексировать или искать на ней; применение $where будет намного медленнее по сравнению с этим. Рекомендуется использовать выражения JavaScript и оператор $where в качестве последнего средства, когда вы не можете структурировать данные каким-либо другим способом или когда вы имеете дело с небольшим подмножеством данных.


Другой и более быстрый подход, который позволяет избежать использования оператора $where , является оператором $regex . Рассмотрим следующий шаблон, который ищет

db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2); 

. Примечание. Из docs :

Если для этого поля существует индекс, MongoDB соответствует регулярному выражению в отношении значений в индексе, который может быть быстрее, чем сканирование коллекции. Дальнейшая оптимизация может произойти, если регулярное выражение является «префиксным выражением», что означает, что все потенциальные совпадения начинаются с одной и той же строки. Это позволяет MongoDB создавать «диапазон» из этого префикса и соответствовать только этим значениям из индекса, попадающего в этот диапазон.

Регулярное выражение является «префиксным выражением», если оно начинается с каретки (^) или левый якорь (\A), а затем строка простых символов. Например, регулярное выражение /^abc.*/ будет оптимизировано путем сопоставления только со значениями из индекса, начинающегося с abc.

Кроме того, в то время как /^a/, /^a.*/, и /^a.*$/ соответствуют эквивалентным строкам, они имеют различные рабочие характеристики. Все эти выражения используют индекс, если существует соответствующий индекс; однако /^a.*/ и /^a.*$/ работают медленнее. /^a/ может остановить сканирование после сопоставления префикса.

90
ответ дан chridam 27 August 2018 в 05:51
поделиться

обновление на Mongo 4.0, оно становится проще и более свободно:

find({name: { $gt: 40 }}, function(err, posts){
    res.render('blog', {posts:posts}); // your code here
});
0
ответ дан celerno 27 August 2018 в 05:51
поделиться

У меня был похожий сценарий, но в моем случае строка не является атрибутом 1-го уровня. Он находится внутри объекта. Здесь я не нашел подходящего ответа. Поэтому я решил поделиться своим решением со всеми вами (надеюсь, это поможет любому, у кого есть подобные проблемы).

Parent Collection 

{
"Child":
{
"name":"Random Name",
"Age:"09"
}
}

Пример: если нам нужно получить только коллекции с длиной имени дочернего имени более 10 символов.

 db.getCollection('Parent').find({$where: function() { 
for (var field in this.Child.name) { 
    if (this.Child.name.length > 10) 
        return true;

}
}})
2
ответ дан Udara Gunathilake 27 August 2018 в 05:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: