2009-07-29 7 views
17

Chciałbym użyć CouchDB do przechowywania niektórych danych dla mnie, a następnie użyć wywołania RESTful API, aby uzyskać dane, które potrzebuję. Moja baza danych jest nazywany „test” i wszystkie moje dokumenty mają podobną strukturę i wyglądać następująco (gdzie hello_world jest identyfikator dokumentu):Jak wykonać sparametryzowaną kwerendę na CouchDB

"hello_world" : {"id":123, "tags":["hello", "world"], "text":"Hello World"} 
"foo_bar" :{"id":124, "tags":["foo", "bar"], "text":"Foo Bar"} 

Co chciałbym być w stanie zrobić, to mieć moje użytkowników wyślij zapytanie takie jak: "Daj mi wszystkie dokumenty, które zawierają słowa" cześć świat ", np. bawiłem się widokami, ale wygląda na to, że pozwolą mi tylko przenieść jedną lub więcej z tych wartości do . „kluczem” część funkcji mapa, która daje mi możliwość zrobić coś takiego:

http://localhost:5984/test/_design/search/_view/search_view?key= „cześć”

Ale to nie pozwala mi pozwolić moim użytkownikom określić ich ciąg zapytania. Na przykład, co jeśli szukają "cześć świat". Musiałbym zrobić dwa pytania: jeden dla "cześć" i jeden dla "świata", wtedy musiałbym napisać kilka javascript, aby połączyć wyniki, usunąć duplikaty, itp (YUCK!). Co ja naprawdę chcę, to być w stanie zrobić coś takiego:

http://localhost:5984/test/_design/search/_view/search_view?term= „Hello World”

następnie użyj parametru „Hello World” w mapie views/zmniejszenia funkcji znaleźć wszystko dokumenty zawierające zarówno "cześć" i "świat" w tablicy znaczników. Czy to możliwe w CouchDB? Czy jest inny sposób na osiągnięcie tego w widoku, o którym nie myślę?

Odpowiedz

19

Widoki CouchDB nie obsługują przeszukiwania pod kątem, wyszukiwania pełnotekstowego ani przecięcia wyników. Wtyczka couchdb-lucene pozwala ci robić te wszystkie rzeczy.

http://github.com/rnewson/couchdb-lucene/tree/master

+0

Chcesz opracować lub podać przykłady? –

+6

Jest jednym z twórców projektu - "Nie możesz tego zrobić, ale ten projekt ci pozwoli." To całkiem dobra odpowiedź. – dnolen

2

Technicznie jest to możliwe, jeśli emitować dla każdego dokumentu, każdy zestaw z PowerSet tagów dokumentu jako klucz. Kluczowy element zestawu musi zostać uporządkowany, a twoje zapytanie będzie musiało również zapytać o zamówione tagi.

function map(doc) { 
    function powerset(array) { ... } 

    powerset_of_tags = powerset(doc.tags) 
    for(i in powerset_of_tags) { 
    emit(powerset_of_tags[i], doc); 
    } 
} 

dla doc {"hello_world" : {"id":123, "tags":["hello", "world"], "text":"Hello World"} ten będzie emitował:

{ key: [], doc: ... } 
{ key: ['hello'], doc: ... } 
{ key: ['world'], doc: ... } 
{ key: ['hello', 'world'], doc: ... } 

Chociaż jest to możliwe, uważam to raczej arkward rozwiązanie. Nie chcę sobie wyobrażać wykorzystania dysku w widoku dla większej liczby tagów. Oczekuję, że liczba wydanych kluczy wzrośnie jak 2^n.

+2

nie jest to zalecane. Wydajność bardzo ucierpi, a jak już wspomniałeś, pamięć dla indeksów wzrośnie spod kontroli. Powyższa wzmianka o couchdb-lucene to właściwy sposób robienia tego, co chce. –

Powiązane problemy