Может ли какая-либо из баз данных noSql извлекать данные по конкретному полю независимо от места расположения файла в документе? - PullRequest
2 голосов
/ 26 июня 2011

Например, если в БД есть следующие документы:

> db.things.find()
[ 
  {"_id" : {"$oid" : "4e0748eecc93747e680421c7"},
          "title" : "aaaa"},
  {"_id" : {"$oid" : "4e074954cc93747e680421c8"},
          "desc" : "bbb",
          "children" : [
            {"title" : "ccc"},
            {"title" : "ddd"}
            ]
  }
  {"_id" : {"$oid" : "4e074a5abbdr4664546e59334"},
          "desc" : "none",
          "children" : [
            {"desc" : "ccc"}
            ]
  }
]

И я хочу получить все документы, в которых есть поле «заголовок», и я не знаю, где это поле расположено в документе. Есть ли у этого типа запросов Mongodb / Couchdb или любой другой документ db?

Ответы [ 2 ]

3 голосов
/ 26 июня 2011

Вы сможете выполнить это с помощью запроса CouchDB Map-Reduce.Вам нужно написать функцию, которая рекурсивно ищет документ в указанном поле.Поскольку CouchDB обновляет только индексы представления постепенно, поиск будет происходить только каждый раз, когда документ либо создается, либо обновляется.

Если вы хотите, чтобы какой-то фактический исходный код написал такую ​​функцию карты, я уверен, что мог бы взбитьчто-тоНо это возможно с CouchDB.:)

РЕДАКТИРОВАТЬ : я потратил несколько минут на взлом рекурсивной функции сканирования.Он не полностью протестирован, но должен быть очень хорошим началом для вас, если он еще не работает.

Я добавил пару удобных функций для тестирования типов, и основная функция называется scan.Для каждого совпадения требуется 2 параметра: вход и функция для вызова.

Он будет проходить через вход.Если вход является объектом, он будет проверять ключи этого объекта, если массив, он будет рекурсивно вызывать scan для каждого из элементов в массиве.Как только ввод является объектом, он проверяет каждую клавишу, если имя title, он вызывает переданную функцию со значением в качестве первого параметра.В противном случае он вызывает scan, если значением является другой объект или массив.

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

function (doc) {
    function is_array(input) {
        return (input.constructor.toString().indexOf("Array") != -1);
    }

    function is_object(input) {
        return (typeof input === "object" && input !== null);
    }

    function scan(obj, func) {
        if (!obj || !is_object(obj)) {
            return false;
        }

        var x;

        if (is_object(obj)) {
            for (x in obj) {
                if (x.toLowerCase() === "title") {
                    func(obj[x]);
                } else {
                    scan(obj[x], func);
                }
            }
        } else if (is_array(obj)) {
            for (x = 0; x <= obj.length; x++) {
                scan(obj[x], func);
            }
        }
    }

    scan(doc, function (value) {
        emit(value);
    });
}
2 голосов
/ 26 июня 2011

Такая функция поиска везде недоступна в MongoDB - по крайней мере, не из коробки и не в общем виде.Map-Reduce со связанной реализацией, имеющей дело с вложенными документами, - это одна опция, а фильтрация на стороне приложения - другая.

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