может ли couchdb делать петли - PullRequest
2 голосов
/ 07 мая 2011

Может ли couchdb делать циклы?

Допустим, у меня есть база интересов, которая имеет 3 поля subject1, subject2, subject3.Например, кошки, питание, волосы или пространство, телескопы, оптика и т. д.

Человек (A) имеет 10 интересов, состоящих из 3 полей каждое.

Еще 10 человек B, C, D.... имеют 10 интересов, каждый из которых состоит из 3 предметов.

Когда человек А входит в систему, я хочу, чтобы система искала всех людей с совпадающими интересами.

В javascript я обычно просматривал бы всеинтересы, а затем найти совпадающие, я думаю, используя две петли.Затем сохраните совпадения в другой базе данных для пользователя, например, "matchinterests".

Есть ли простой способ сделать это в couchdb по сравнению с mysql - что кажется очень сложным.

Спасибо, Дэн

Ответы [ 2 ]

3 голосов
/ 07 мая 2011

Мне кажется, я понимаю, о чем вы спрашиваете. Ответ довольно прост с Map / Reduce.

Скажем, у вас есть следующие документы людей:

{
   "name": "Person A",
   "interests" [ "computers", "fishing", "sports" ]
}
{
   "name": "Person B",
   "interests" [ "computers", "gaming" ]
}
{
   "name": "Person C",
   "interests" [ "hiking", "sports" ]
}
{
   "name": "Person D",
   "interests" [ "gaming" ]
}

Возможно, вы захотите указать свой ключ как интерес, со значением в качестве имени человека (или _id).

function (doc) {
   for (var x = 0, len = doc.interests.length; x < len; x++) {
      emit(doc.interests[x], doc..name);
   }
}

Результаты вашего просмотра будут выглядеть так:

  • компьютеры => Лицо A
  • компьютеры => Человек B
  • Рыбалка => Человек А
  • gaming => Person B
  • gaming => Person D
  • пеший туризм => человек C
  • спорт => человек А
  • спорт => человек C

Чтобы получить список людей, интересующих компьютеры, вы можете просто отправить key="computers" как часть строки запроса.

Если вы хотите добавить функцию уменьшения на карту, вы можете просто использовать _count (ярлык для использования скомпилированной функции уменьшения), и вы можете получить количество всех людей с особым интересом, вы даже можете использовать чтобы ограничить интересы, которые вы запрашиваете, чтобы строить свои отношения.

0 голосов
/ 07 мая 2011

Когда человек А входит в систему, я хочу, чтобы система искала всех людей с совпадающими интересами.

SELECT i_them.* FROM interests AS i_me
INNER JOIN interests AS i_them ON (i_them.person != i_me.person) AND
 ((i_them.subject1 IN (i_me.subject1, i_me.subject2, i_me.subject3)) OR
  (i_them.subject2 IN (i_me.subject1, i_me.subject2, i_me.subject3)) OR 
  (i_them.subject3 IN (i_me.subject1, i_me.subject2, i_me.subject3)))
WHERE i_me.person = 'A' 

Это то, что вы хотели сделать?

Если вы разрабатываете свои таблицы немного умнее, хотя делаете это как

SELECT DISTINCT them.* FROM person AS me
INNER JOIN interest AS i_me ON (i_me.person_id = me.id)
INNER JOIN interest AS i_them ON (i_them.subject = i_me.subject)
INNER JOIN person AS them ON (them.id = i_them.person.id AND them.id != me.id)
WHERE me.name = 'A'

Используя следующие таблицы

table interest
  id integer primary key autoincrement
  person_id integer //links to person table
  subject varchar //one subject per row.
  +-----+-----------+---------+
  | id  | person_id | subject |
  +-----+-----------+---------+
  | 1   | 3         | cat     |
  | 2   | 3         | stars   |
  | 3   | 3         | eminem  |
  | 4   | 1         | cat     |
  | 5   | 1         | dog     |
  | 6   | 2         | dog     |
  | 7   | 2         | cat     | 

table person
  id integer primary key autoincrement
  name varchar
  address varchar
  +-----+------+---------+
  | id  | name | address |
  +-----+------+---------+
  | 1   | A    | here    |
  | 2   | Bill | there   |
  | 3   | Bob  | everyw  |

result
+-----+------+---------+
| id  | name | address |
+-----+------+---------+
| 2   | Bill | there   |
| 3   | Bob  | everyw  |

Вот как (что вы называете) «зацикливание» в SQLработает ...

Сначала вы берете человека с именем 'A' из таблицы.

me.id me.name me.address
| 1   | A    | here    |

Вы просматриваете все интересы

me.id me.name me.address i_me.subject
| 1   | A    | here      | cat
| 1   | A    | here      | dog

Затем вы сопоставляете интересы всех остальных

me.id me.name me.address i_me.subject i_them.subject i_them.person_id
| 1   | A    | here      | cat        | cat          | 3
| 1   | A    | here      | cat        | cat          | 2
| 1   | A    | here      | dog        | dog          | 2

И затем вы сопоставляете человека с интересами его (кромедля меня, конечно)

me.id me.name me.address i_me.subject i_them.subject i_them.person_id them.name
| 1   | A    | here      | cat        | cat          | 3              | Bob 
| 1   | A    | here      | cat        | cat          | 2              | Bill 
| 1   | A    | here      | dog        | dog          | 2              | Bill

Затем вы возвращаете только данные из them и «выбрасываете» остальные, и удаляете дублирующиеся строки DISTINCT.

Надеюсь, это поможет.

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