我需要實現一個用戶定義的規則引擎像上面的(使用技術:的NodeJS +的MongoDB)
我遇到一個SO Q的這的確在MySQL數據存儲,但我沒有知道如何查詢數據,並通過JavaScript得到它的eval:
What is an appropriate data structure and database schema to store logic rules?
關於設計&實現任何想法是高度讚賞。
Sunny
我需要實現一個用戶定義的規則引擎像上面的(使用技術:的NodeJS +的MongoDB)
我遇到一個SO Q的這的確在MySQL數據存儲,但我沒有知道如何查詢數據,並通過JavaScript得到它的eval:
What is an appropriate data structure and database schema to store logic rules?
關於設計&實現任何想法是高度讚賞。
Sunny
使用所顯示的規則構建SQL查詢將非常簡單。與構建mongo查詢不一樣的情況。
我提出了類似的發動機,其中i存儲的規則作爲SQL規則,然後寫一個模塊來構造從SQL查詢蒙戈查詢(一個簡單的一個)。
爲了配合對JavaScript對象蒙戈規則,我所用的篩庫(不具有相同的正則表達式的支持,蒙戈查詢引擎) - https://github.com/crcn/sift.js
因此,如果可能的話,我會建議你存儲數據在SQL數據庫,然後應用SQL規則,你構建你做了正確的轉義後(以避免SQL注入)
這是我曾經在前端構建SQL類型的規則的功能 -
(rule
這裏是映射到UI中每一行的表達式數組)
function getRuleString(rule) {
var andOrStack = [];
var lastExpressionDepth = 0;
var tempRuleString = '';
var countOpenBrackets = 0;
if(!rule || !rule.expressionRows) {
return '';
}
rule.expressionRows.forEach(function(expressionRow, index) {
expressionRow.depth = parseInt(expressionRow.depth, 10);
if(lastExpressionDepth !== expressionRow.depth) {
// if this is an outer expression than the previous
if((lastExpressionDepth - expressionRow.depth) > 0) {
for(var i=0; i<(lastExpressionDepth - expressionRow.depth); i++) {
tempRuleString += ') ';
}
tempRuleString += ' ' + andOrStack.pop() + ' ';
} else {
tempRuleString += ' ' + andOrStack.pop() + ' (';
}
lastExpressionDepth = expressionRow.depth;
} else {
if(index > 0) {
tempRuleString += ' ' + andOrStack.pop() + ' ';
}
}
tempRuleString += expressionRow.firstColumn + ' ' + expressionRow.operator + ' "' + expressionRow.expression + '"';
andOrStack.push(expressionRow.andOr);
});
tempRuleString += Array.apply(null, Array(tempRuleString.split('(').length-tempRuleString.split(')').length)) // jshint ignore: line
.map(String.prototype.valueOf, ') ').join('');
return tempRuleString;
}
下面是一個簡單的例子,說明一個模式和一個MongoDB查詢類似於你給出的例子。爲了簡單起見,我在mongo shell中寫了這個。 node.js版本將會類似。希望這會給你一個想法如何開始。
首先,我們的一些文件添加到用戶集合:
db.subscriber.insert({
date_added: ISODate('2014-01-01'),
first_name: 'Fred',
language: 'en'
})
db.subscriber.insert({
date_added: ISODate('2014-01-10'),
first_name: 'Jorge',
language: 'es'
})
db.subscriber.insert({
date_added: ISODate('2014-01-20'),
first_name: 'Jimmy',
language: 'en'
})
db.subscriber.insert({
date_added: ISODate('2014-01-30'),
first_name: 'Frodo',
language: 'sjn'
})
這裏是類似於你給的例子中的查詢,匹配滿足基於日期範圍,第一個字符串匹配條件的任何文件名稱或語言的精確匹配:
db.subscriber.find({
$or: [
{date_added: {$gte: ISODate('2014-01-30')}},
{first_name: /Jim/},
{language: 'es'}
]})
這裏是由查詢返回的文件:
{
"_id" : ObjectId("530f6edc32292f1f130aae16"),
"date_added" : ISODate("2014-01-10T00:00:00Z"),
"first_name" : "Jorge",
"language" : "es"
},
{
"_id" : ObjectId("530f6edc32292f1f130aae17"),
"date_added" : ISODate("2014-01-20T00:00:00Z"),
"first_name" : "Jimmy",
"language" : "en"
},
{
"_id" : ObjectId("530f6edc32292f1f130aae18"),
"date_added" : ISODate("2014-01-30T00:00:00Z"),
"first_name" : "Frodo",
"language" : "sjn"
}
這是否幫助您開始?