Выберите длину строки в mongodb

Как вы запрашиваете mongodb, чтобы найти длину конкретной строки/текстового поля?

И как бы вы нашли максимальную длину набора запросов?

Ответ 1

К сожалению, структура агрегации не поддерживает оператора "len", чтобы автоматически преобразовывать строки в их длину во время выполнения запроса. Поэтому вы должны решить это в своем собственном коде. Вы могли

  • используйте функцию MapReduce для вычисления длины строк
  • для строк и расчета их длины на уровне приложения

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

Ответ 2

Небо - предел! Нет, на самом деле это 16 MB для документа в mongodb. Это может быть максимальная длина строки в записях.

Чтобы найти максимальную длину в наборе запросов, вы можете выполнить эту работу:

  • Сохраняйте длину текста вместе с самим текстом.
  • Отсортируйте результирующий набор по убыванию.
  • Получить первый элемент с максимальной длиной.

Ответ 3

как использовать вместо этого регулярное выражение.

> db.apps.find({$where:"(this.id.length gt 6) && (this.id.length lt 15) " } ).count();
2548
> db.apps.find({$where:" (this.id.length gt 6) && (this.id.length lt 15) " } ).explain();
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 2548,
    "nscannedObjects" : 88736,
    "nscanned" : 88736,
    "nscannedObjectsAllPlans" : 88736,
    "nscannedAllPlans" : 88736,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 1,
    "nChunkSkips" : 0,
    "millis" : 1523,
    "indexBounds" : {

    },
    "server" : "shuhaimac.local:27017"
}
> db.apps.find({id:/\w{7,16}/i}).count();
2548
> db.apps.find({id:/\w{7,16}/i}).explain();
{
    "cursor" : "BtreeCursor id_1 multi",
    "isMultiKey" : false,
    "n" : 2548,
    "nscannedObjects" : 2548,
    "nscanned" : 88736,
    "nscannedObjectsAllPlans" : 2548,
    "nscannedAllPlans" : 88736,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 122,
    "indexBounds" : {
        "id" : [
            [
                "",
                {

                }
            ],
            [
                /\w{7,16}/i,
                /\w{7,16}/i
            ]
        ]
    },
    "server" : "shuhaimac.local:27017"
}

Ответ 4

Итак, я надеюсь, что это поможет.:-) Я столкнулся с той же проблемой - и мне потребовалось некоторое время, чтобы заставить работу по сокращению карты работать.

$response = $Mongo->yourdb->command(array(
    "mapreduce" => "yourcollection",
    "map" => new MongoCode(" function() { emit( this.groupbykey, this.thestring.length ); } "),
    "reduce" => new MongoCode(" function(k, vals) { return Math.max.apply(null, vals); } "),
    "query" => array("groupbykey" => "somevalue"),
    "out" => array("inline" => 0)
));

Отклик будет содержать результат уменьшения карты

Array
(
    [results] => Array
        (
            [0] => Array
                (
                    [_id] => groupbykeyvalue
                    [value] => 106
                )

        )

    [counts] => Array
        (
            [input] => 7341
            [emit] => 7341
            [reduce] => 76
            [output] => 1
        )

    [timeMillis] => 189
    [timing] => Array
        (
            [shardProcessing] => 171
            [postProcessing] => 17
        )

    [shardCounts] => Array
        (
            [someshard:27017] => Array

Удачи, дайте мне знать, если вам нужен другой вариант!

Ответ 5

Начиная с Mongo 3.4, оператор агрегации $strLenCP может использоваться для получения длины строки:

// { a: "Hello World" }
// { a: "42" }
// { a: "Hello World!" }
db.collection.aggregate([{ $addFields: { length: { $strLenCP: "$a" } } }])
// { a: "Hello World",  length: 11 }
// { a: "42",           length: 2 }
// { a: "Hello World!", length: 12 }

и чтобы получить максимальную длину из всех документов через стадию $group/ $max:

db.collection.aggregate([
  { $group: { _id: null, longest: { $max: { $strLenCP: "$a" } } } }
])
// { "_id" : null, longest: 12 }

Ответ 6

В отличие от SQL MongoDB действительно не знает длину полей как таковых. В лучшем случае, когда он индексирует, он знает, что поле находится под 1024 байтами или нет.

Таким образом, вам, вероятно, придется исправить клиентскую сторону. Вы можете использовать $where здесь, но я думаю, что вы смотрите на это неправильно, если хотите это сделать.

Вы также можете использовать и MR здесь, как утверждает @Philipp, но опять же вы, вероятно, смотрите на неправильную вещь здесь.

Запрос в MongoDB на самом деле является документом BSON. Таким образом, максимальная длина набора запросов (в зависимости от того, что вы определяете как "набор запросов" ) всегда равна 16 МБ (на данный момент).

Многие драйверы предоставляют средства, позволяющие кодировать структуру (хэш или диктофон или что-то еще) в BSON, позволяя судить о длине закодированной строки, чтобы понять размер вашего запроса.