2015-04-06 4 views
1

На моем RethinkDB 1.16.2-1 на Linux у меня есть таблица «продуктов», у которой есть массив «категорий» и массив «моделей»:Возврат MAX() и MIN() в одном запросе

{ 
"name": "ABC Cable Series" , 
"categories": [ 
    "Analog Audio>Instrument>Cables" , 
    "Analog Audio>Microphone Cables" 
    ] , 
"models": [ 
    { 
    "modelCode": "ABC-1" , 
    "ssp": 11.95 , ... 
    } , 
    { 
    "modelCode": "ABC-2" , 
    "ssp": 15.95 , ... 
    } 
] 
} , ... 

Мне нужно получить как модель минимальной, так и максимальной цены (ssp) в продуктах, содержащих данную категорию продуктов. Я в настоящее время получить максимальную цену, как это:

r.db("store").table("products").filter(function(prod) { 
    return prod("categories").contains(
    function(cat){return cat.match("^Analog Audio>") 
    }) 
}).concatMap(function(doc) { 
    return doc("models")("ssp") 
}).max() 

кроме работы 2 запросов, есть более эффективный способ, чтобы получить значение как MAX и MIN в одном запросе?

+0

С другой стороны, лучше всего было бы вернуть список значений SSP и вычислить MAX и MIN в приложении (массив будет содержать максимум 200 цен). Как вы думаете? – Smyrnian

ответ

0

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

r.db('test').table('products').filter(function(prod) { 
    return prod("categories").contains(
    function(cat){return cat.match("^Analog Audio>") 
    }) 
}).concatMap(function(doc) { 
    return doc("models")("ssp") 
}) 
.coerceTo('array') // Convert Stream to Array 
.do(function (rows) { // Pass array to to `.do` 
    return {   // Return Object 
    max: rows.max(), 
    min: rows.min() 
    } 
}) 
+0

Это прекрасно работает, спасибо. Для работы на моем сервере требуется всего около 100 мс, что довольно хорошо, учитывая сложность запроса. Я должен сказать, что одной отрицательной точкой в ​​использовании RethinkDB пока является крутая неинтуитивная кривая обучения ReQL (по крайней мере, для меня). Большинство разработчиков уже знают SQL, поэтому я думаю, что большинство из них предпочли бы SQL или даже расширенный SQL для этой БД, что в противном случае является удивительным. – Smyrnian

1

Вы можете также использовать reduce (http://rethinkdb.com/api/javascript/reduce/), чтобы вычислить оба значения без преобразования всех данных в массив первого:

r.db("store").table("products").filter(function(prod) { 
    return prod("categories").contains(
    function(cat){return cat.match("^Analog Audio>") 
    }) 
}).map(function(doc) { 
    return { 
     min: doc("models")("ssp").min(), 
     max: doc("models")("ssp").max() 
    } 
}).reduce(function (le, ri) { 
    return { 
     min: r.expr([le("min"), ri("min")]).min(), 
     max: r.expr([le("max"), ri("max")]).max() 
    } 
}) 
+0

Спасибо, Дэниэл. Однако даже после исправления недостающей фигурной скобки в конце, я получаю «TypeError: undefined is not a function» – Smyrnian

+0

Простите об этом. Проблема заключалась в том, что я назвал один из аргументов функции в функции сокращения 'r', который замаскировал модуль' r', который я использую для 'r.expr'. Я исправил его в своем посте. –

+0

Без проблем, спасибо Даниэлю. Быстрые один: В чем разница между:. возвратным продом ("Категория") содержит ( функции (кошку) {возвращение cat.match ("^ Analog Audio>") }) и возвращения лезвие («категории») содержит (r.row.match («^ Analog Audio>»)) – Smyrnian

Смежные вопросы