RethinkDB: получение всех документов, содержащих строку в любом поле

Я хочу выполнить запрос, который вернет все документы, содержащие заданную строку в ЛЮБОМ из своих полей. Например, скажем, у меня есть таблица «users», и я ищу все документы, содержащие «john», возвращаемый результат может быть таким:

[{"first_name": "jhon", "last_name": "watson"}, {"first_name": "elton", "last_name": "john"}, {"first_name": "sherlock", "last_name": "holmes", "best_friend": "john watson"}]

Как мне это сделать в rethinkdb? ответ javascript подойдет, реализация python будет лучше.


person user3162581    schedule 05.01.2014    source источник


Ответы (3)


К сожалению, этот запрос усложняется тем фактом, что в ReQL нет функции values, такой как python. Однако у него есть функция keys, поэтому давайте просто воспользуемся ею, чтобы создать функцию values следующим образом:

def values(doc):
    return doc.keys().map(lambda x: doc[x])

Теперь, когда у нас есть, найти документ, содержащий строку в одном из ключей, довольно просто:

def has_str(doc, str):
    return values(doc).map(match(str)).reduce(lambda x,y: x | y)

Наконец, мы можем собрать все вместе:

r.table("users").filter(lambda doc: has_str(doc, str))

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

person Joe Doliner    schedule 05.01.2014

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

r.db('database').table('table).filter(function(doc) {
  return doc.coerceTo('string').match('querystring');
});

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

person Mark    schedule 11.05.2015

Для любого, кто оказался здесь, пытаясь понять это в javascript, это примерно означает:

function values(doc) {
  return doc.keys().map(function(key) {
    return doc(key);
  });
}

function contains(doc, string) {
  return values(doc).map(function(val) {
    return r.branch(val.match(string), true, false);
  }).reduce(function(left, right) {
    return left.or(right);
  });
}

var query = r.db('database').table('table').filter(function(doc) {
  return contains(doc, "some string");
});

query.run().then(function(results) {
  console.log(results);
});

Улучшения приветствуются!

person mbroadst    schedule 07.05.2015