2010-04-06 12 views
10

Jak mogę wykonać kwerendę równoważną "wybierz top 10" w kanapie kanapie?Wybierz top/ostatnie 10 w couchdb?

Na przykład mam "schemat" tak:

title body modified 

i chcę, aby wybrać 10 ostatnio zmodyfikowane dokumenty.

Jako dodatkowa premia, jeśli ktoś może wymyślić sposób, aby zrobić to samo tylko dla każdej kategorii. Z tego powodu:

title category body modified 

zwraca listę 10 ostatnich dokumentów w każdej kategorii.

Zastanawiam się tylko, czy takie zapytanie jest możliwe w couchdb.

+0

Czy istnieje powód, dla którego nie chcesz robić tego ręcznie? Pierwsze zapytanie do dostępnych kategorii, następnie zapytaj listy według kategorii. Wykonuje załadowanie drugiego zapytania, czyli prawie jak w zapytaniu. –

+0

Mogę to zrobić tak - ale moje pytanie brzmi, czy coś takiego jest możliwe w couchdb, w jednym zapytaniu. Na przykład można to zrobić w sql z naprawdę skomplikowaną zagnieżdżoną instrukcją select. – drozzy

Odpowiedz

3

tutaj jest to, co trzeba zrobić.

funkcja Map

function(doc) 
{ 
    if (doc.category) 
    { 
    emit(['category', doc.category], doc.modified); 
    } 
} 

to trzeba funkcję listy, że grupy nich, może być temped nadużywać redukuj i to zrobić, ale to prawdopodobnie będzie rzucać błędów, nie zmniejszając wystarczająco szybko z dużych zbiorów danych.

function(head, req) 
{ 
    % this sort function assumes that modifed is a number 
    % and it sorts in descending order 
    function sortCategory(a,b) { b.value - a.value; } 
    var categories = {}; 
    var category; 
    var id; 
    var row; 
    while (row = getRow()) 
    { 
    if (!categories[row.key[0]]) 
    { 
     categories[row.key[0]] = []; 
    } 
    categories[row.key[0]].push(row); 
    } 
    for (var cat in categories) 
    { 
    categories[cat].sort(sortCategory); 
    categories[cat] = categories[cat].slice(0,10); 
    } 
    send(toJSON(categories)); 
} 

można uzyskać wszystkie kategorie Top 10 teraz z

http://localhost:5984/database/_design/doc/_list/top_ten/by_categories 

i uzyskać dokumenty z

http://localhost:5984/database/_design/doc/_list/top_ten/by_categories?include_docs=true 

teraz można wyszukać to z kilku zakresów POST i limitu które kategorie

curl -X POST http://localhost:5984/database/_design/doc/_list/top_ten/by_categories -d '{"keys":[["category1"],["category2",["category3"]]}' 

nie można również zakodować kodu 10 i przekazać numeru za pomocą zmiennej req.

Oto więcej Zobacz/List trickery.

+0

Fajnie, przetestuję to i skontaktuję się z Tobą! – drozzy

+0

Nie przetestowałem tej odpowiedzi, ale i tak ją zaakceptuję, ponieważ nie będę już pracował z couchdb. – drozzy

7

Aby uzyskać pierwsze 10 dokumentów z bazy danych, można użyć opcji zapytania o limit. E.g. dzwoniąc pod numer

http://localhost:5984/yourdb/_design/design_doc/_view/view_name?limit=10 

Otrzymujesz pierwszych 10 dokumentów.

Wyświetl rzędy są posortowane według klucza; dodanie malejąco = true w querystringu spowoduje odwrócenie kolejności. Możesz także wysyłać tylko te dokumenty, które są zainteresowane, ponownie używając kwerendy, aby wybrać klucze, które Cię interesują. Więc w widoku napisać funkcję mapy jak:

function(doc) { 
    emit([doc.category, doc.modified], doc); 
} 

I kwerendy tak:

http://localhost:5984/yourdb/_design/design_doc/_view/view_name?startkey=["youcategory"]&endkey=["youcategory", date_in_the_future]&limit=10&descending=true 
+0

Czy to drugie zapytanie faktycznie wybierze 10 ostatnich pozycji w każdej z kategorii? Czy po prostu 10 najnowszych przedmiotów z jednej kategorii? – drozzy

+0

Ups. Źle odczytałem twoje pytanie. Wybiera ostatnie 10 pozycji z jednej kategorii. – filippo

0

niewielka korekta. nie sortowałem dopóki nie dodałem słowa kluczowego "return" w funkcji sortCategory.Powinno być tak:

function sortCategory(a,b) { return b.value - a.value; }