2014-12-09 4 views
2

У меня есть база данных, которая имеет следующую структуру:структура базы данных для metaquery

+------+------+--------+-------+--------+-------+ 
| item | type | color | speed | length | width | 
+------+------+--------+-------+--------+-------+ 
| 1 | 1 |  3 |  1 |  2 |  2 | 
| 2 | 1 |  5 |  3 |  1 |  1 | 
| 3 | 1 |  6 |  3 |  1 |  1 | 
| 4 | 2 |  2 |  1 |  3 |  1 | 
| 5 | 2 |  2 |  2 |  2 |  1 | 
| 6 | 2 |  4 |  2 |  3 |  1 | 
| 7 | 2 |  5 |  1 |  1 |  2 | 
| 8 | 3 |  1 |  2 |  2 |  2 | 
| 9 | 4 |  4 |  3 |  1 |  2 | 
| 10 | 4 |  6 |  3 |  3 |  2 | 
+------+------+--------+-------+--------+-------+ 

Я хотел бы эффективно запроса, какая комбинация полей справедливы. Так, например, я хотел бы запросить базу данных по следующему адресу:

Какие значения цвета действительны, если тип 1?

ans: [3, 5, 6] 

Какие значения скорости действительны, если тип 2, а цвет 2?

ans: [1, 2] 

Какие значения типа действительны, если длина равна 2 и ширина равна 2?

ans: [1, 2] 

Эквиваленты SQL являются:

SELECT DISTINCT `color` FROM `cars` WHERE `type` =2 
SELECT DISTINCT `speed` FROM `cars` WHERE `type` =2 AND `width` =2 
SELECT DISTINCT `type` FROM `cars` WHERE `length` =2 AND `width` =2 

Я планирую использовать базу данных на основе облака (Cloudant DBAAS - на основе CouchDB). Как это лучше всего реализовать, имея в виду, что могут быть тысячи предметов с десятками полей?

+0

Я не уверен, я понимаю ваши требования правильно.Это то, что вы пытаетесь сделать в первом примере, эквивалентном SQL-запросу типа «Выбрать цвет, где type = 1»? Это очень легко перевести на представления CouchDB. –

+0

Обновлен вопрос с эквивалентными SQL-запросами. – Terry

+0

@Terry вы решили эту проблему? –

ответ

0

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

{ 
    "_id": "1db91338150bfcfe5fcadbd98fe77d56", 
    "_rev": "1-83daafc1596c2dabd4698742c2d8b0cf", 
    "item": 1, 
    "type": 1, 
    "color": 3, 
    "speed": 1, 
    "length": 2, 
    "width": 2 
} 

Обратите внимание на _id и _rev полей были автоматически созданы Cloudant для этого примера.

Затем можно создать вторичный индекс на type поле:

function(doc) { 
    if(doc.type) 
     emit(doc.type); 
} 

Для поиска с помощью type поля:

https://accountname.cloudant.com/dashboard.html#database/so/_design/ddoc/_view/col_for_type?key=1&include_docs=true

Вторичный индекс на полях type и width:

function(doc) { 
    if(doc.type && doc.width) 
    emit([doc.type, doc.width]); 
} 

Для поиска с использованием type и width поля:

https://accountname.cloudant.com/dashboard.html#database/so/_design/ddoc/_view/speed_for_type_and_width?key=[1,2]&include_docs=true

Вторичный индекс на полях length и width:

function(doc) { 
    if (doc.length && doc.width) 
     emit([doc.length, doc.width]); 
} 

Для поиска с использованием length и width поля:

https://accountname.cloudant.com/dashboard.html#/database/so/_design/ddoc/_view/type_for_length_and_width?key=[2,2]&include_docs=true

Полный дизайн документ здесь:

{ 
    "_id": "_design\/ddoc", 
    "_rev": "3-c87d7c3cd44dcef35a030e23c1c91711", 
    "views": { 
    "col_for_type": { 
     "map": "function(doc) {\n if(doc.type)\n  emit(doc.type);\n}" 
    }, 
    "speed_for_type_and_width": { 
     "map": "function(doc) {\n if(doc.type && doc.width)\n emit([doc.type, doc.width]);\n}" 
    }, 
    "type_for_length_and_width": { 
     "map": "function(doc) {\n if (doc.length && doc.width)\n  emit([doc.length, doc.width]);\n}" 
    } 
    }, 
    "language": "javascript" 
} 
Смежные вопросы