Полное соединение / пересечение в couchdb - PullRequest
1 голос
/ 26 октября 2010

У меня есть несколько документов, которые имеют 2 набора атрибутов: tag и lieu. Вот пример того, как они выглядят:

{
  title: "doc1",
  tag: ["mountain", "sunny", "forest"],
  lieu: ["france", "luxembourg"]
},
{
  title: "doc2",
  tag: ["sunny", "lake"],
  lieu: ["france", "germany"]
},
{
  title: "doc3",
  tag: ["sunny"],
  lieu: ["belgium", "luxembourg", "france"]
}

Как я могу отобразить / уменьшить и запросить мою БД, чтобы иметь возможность получить только пересечение документов, которые соответствуют этим критериям:

  • lieu: ["Франция", "Люксембург"]
  • тег: ["солнечный"]

Возвращает: doc1 и doc3

Я не могу понять, какая карта формата / редукция может вернуться, чтобы иметь возможность иметь только один запрос. Что я делаю сейчас: отправляю каждый тег / lieu как ключ и id документов, связанный как значение, затем уменьшаем для каждого ключа массив идентификаторов документов. Затем из моего приложения я запрашиваю это представление, на стороне приложения делаю пересечение документов (возьмите только документы, которые имеют 3 ключа (люксембург, франция и солнечный), а затем запрашиваю couchdb с идентификаторами этих документов для получения фактических документов Я чувствую, что это не правильный / лучший способ сделать это?

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

Спасибо!

1 Ответ

1 голос
/ 28 октября 2010

Это будет неловко. Основная идея заключается в том, что вам нужно создать представление, в котором функция карты выдает каждую возможную комбинацию тегов и стран в качестве ключа, а функция сокращения отсутствует. Таким образом, поиск ["france","luxembourg"] вернет все документы, которые испустили этот ключ (и, следовательно, находятся на пересечении), потому что представления без функции сокращения возвращают исходящий документ для каждой записи. Таким образом, вам нужно сделать только один запрос.

Это вызывает много выбросов, но вы можете уменьшить это число, отсортировав теги как при выдаче, так и при поиске (автоматически превратить ["luxembourg","france"] в ["france","luxembourg"]), а также воспользовавшись возможностью CouchDB префиксы запросов (это означает, что отправка ["belgium","france","luxembourg"] позволит вам соответствовать поискам ["belgium"] и ["belgium","france"]).

В приведенном выше примере для стран вы можете указать только:

// doc 1
emit(["luxembourg"],null);
emit(["france","luxembourg"],null);

// doc 2
emit(["germany"],null);
emit(["france","germany"],null);

// doc 3
emit(["luxembourg"],null);
emit(["belgium","luxembourg"],null);
emit(["france","luxembourg"],null);
emit(["belgium","france","luxembourg"],null);

В любом случае, для сложных запросов, подобных этому, рассмотрите комбинацию CouchDB-Lucene.

...