Code Monkey home page Code Monkey logo

Comments (10)

CacheControl avatar CacheControl commented on May 14, 2024 2

@arsalans this feature is now available in 1.4.0 as an allowUndefinedFacts engine option. Please see the updated docs

from json-rules-engine.

CacheControl avatar CacheControl commented on May 14, 2024

thanks for the feedback @arsalans

Can you elaborate on why you'd prefer that approach? i.e., what's desirable about it silently treating the undefined fact as falsey, as opposed to simply explicitly passing in a default value of {personalFoulCount: 0} to run()?

Getting into specifics on this particular instance, I think a default value makes a lot of sense, since any player on a team will always have an integer value for their foul count, starting at 0.

from json-rules-engine.

arsalans avatar arsalans commented on May 14, 2024

from json-rules-engine.

CacheControl avatar CacheControl commented on May 14, 2024

@arsalans yep, I think your situation makes the case for your request quite well.

We could certainly add an option to the engine constructor to turn off hard enforcement of fact existence, e.g. let engine = new Engine(rules, { ignoreUnregisteredFacts: true })

However, I want to be transparent about the capabilities of this project, and make sure it's the right solution for your task. Although I'd love to someday make this project smart enough to optimally select the correct rules to run, that's not a current capability. So if you had 1,000 rules and fed them into the rules engine, it would run all 1,000 (most would fail immediately on the first condition and therefore be very quick to execute). I've done some load testing at this sort of volume and the results were fine for my particular use case at the time; if I recall the entire run completed in well under 10 milliseconds. That may sound like a reasonable benchmark, but it's important to remember that Javascript blocks while doing CPU bound tasks. I may eventually look into implementing a web worker model to offload the work from the main thread if there's enough interest, but that's currently not on the roadmap. This project really is targeted as a lightweight solution for executing dozens or hundreds of rules (not thousands). In any event, I'd encourage you to do some simple benchmarking before committing to this or any other rules engine library.

Now, depending on your situation, you may be able to do some basic filtering of your rules and selectively feed a subset into the engine to be run. This pattern works well when there's an obvious property you can segment rules using. For example, if you needed to run only the rules for the current customer, you could do something like:

let rules = require('./all-my-rules') // entire subset
let targetCustomerId = req.params.customerId
let rulesToRun = rules.filter(rule => rule.customerId === targetCustomerId)
engine.run(rulesToRun)

Please do let me know your thoughts

from json-rules-engine.

arsalans avatar arsalans commented on May 14, 2024

@CacheControl Thank you very much for your insights into this matter.

ignoreUnregisteredFacts flag will really come in handy.

We have been thinking about breaking down 1000 rules into multiple rulesets so that we are not running all the 1000 rules for every request. Your example for filtering helps, however, would you suggest a way where we can have lets say 20 rulesets and then 20 engines running for them (one engine for one ruleset)? Can we group rules by a ruleset name and then filter on the name of the ruleset instead of filtering on the field name?

Let me know your thoughts.

from json-rules-engine.

CacheControl avatar CacheControl commented on May 14, 2024

@arsalans The filtering you described makes sense to me and should work fine, provided you can identify which group(s) of rules to run (obviously if you have 10 batches of 100 rules each, if you have to run all 10 batches the performance will be the same as simply running all 1000 in a single engine). I think as long as you're running hundreds of rules (not thousands), you'll be fine). Having a different engine to run each batch of rules is fine pattern to follow as well.

I can probably build in the new flag you require fairly easily. Give me a couple days to clear some time in my schedule and I can probably get it built by sometime next week.

from json-rules-engine.

arsalans avatar arsalans commented on May 14, 2024

@CacheControl Thank you very much, I am looking forward to test this out :)

You get a medal -> 🥇

from json-rules-engine.

arsalans avatar arsalans commented on May 14, 2024

@CacheControl Just to confirm, what is going to be the outcome of the following when all the changes are made:

If my facts are these:

let facts = {
    gameDuration: 40
  };

And my rule is:

engine.addRule({
    conditions: {
      any: [{
        fact: 'personalFoulCount',
        operator: 'greaterThanInclusive',
        value: 5
      },
        {
          fact: 'gameDuration',
          operator: 'equal',
          value: 40
        }]
    },
    event: {  // define the event to fire when the conditions evaluate truthy
      type: 'fouledOut',
      params: {
        message: 'Player has fouled out!'
      }
    }
  });

I am expecting the following outcome (as the gameDuration fact is still valid and they were in the ANY clause):

'Player has fouled out!'

from json-rules-engine.

arsalans avatar arsalans commented on May 14, 2024

In another scenario, if my facts are these:

let facts = {
    gameDuration: 40
  };

And my rule is:

engine.addRule({
    conditions: {
      all: [{
        fact: 'personalFoulCount',
        operator: 'greaterThanInclusive',
        value: 5
      },
        {
          fact: 'gameDuration',
          operator: 'equal',
          value: 40
        }]
    },
    event: {  // define the event to fire when the conditions evaluate truthy
      type: 'fouledOut',
      params: {
        message: 'Player has fouled out!'
      }
    }
  });

I am expecting that the rule will not produce an event as both facts are in the ALL condition and one is not present.

from json-rules-engine.

CacheControl avatar CacheControl commented on May 14, 2024

@arsalans yep, we're aligned. Any unregistered fact will simply be treated as a falsey condition. This could mean a rule still evaluates truthy, as in the ANY scenario you mentioned. I'll attempt to come up with a better term than ignoreUnregisteredFacts that better explains the behavior

from json-rules-engine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.