00:00
了解了个体模式里边的量词,接下来我们再来介绍一下个体模式当中的条件conditions啊,其实我们知道对于个体模式它匹配事件的这个过程来讲,最核心的要点其实就是这个匹配条件啊,就是我们在这个代码当中点where里边传的这个simple condition,我们这里边定义的就是要求当前数据的event必须是这样的话,才能够把当前事件提取出来,匹配上我们这里的这个个体模式。而所谓的量词只不过是基于这样的一个匹配规则去做了一个重复匹配而已啊,所以真正的核心一个模式判断。的核心就是这里的条件。那对于条件的定义呢,我们可以看到这里主要就是调用了一个点where方法,这是基于什么数据类型去调的,点where方法呢?其实简单点进去我们就会看到啊,这里返回的其实就是一个pattern。
01:06
而后边每一步调用啊,包括where之后得到的也是pattern啊,这里nes之后得到的也是pattern,我们这里边在定义一个pattern的过程当中,定义一个模式的过程当中,每一步方法调用返回的数据类型都是pattern。然后每一步方法调用都是基于pattern对象去进行的调用啊,这也就是为什么我们当前这一套API叫做pattern API这个数据类型啊,基本的数据类型都是P,所以我们这里面基于patternon去调了一个点where方法里边就可以传入一个当前的条件。那这里面我们传入的是一个simple condition,那顾名思义,这是一个简单条件,那照理来讲也就应该有其他的条件,有更加复杂的条件。在Li cp里边,对于这个条件可以分成这么几种类型,主要有简单条件,迭代条件,复合条件,还有终止条件这么几种类型啊。
02:11
那呃,当然了,另外还有一个比较特殊的,就是可以指定匹配事件的子类型,就直接调一个方法叫subant啊,那首先我们可以看到这个限定子类型的这个方法就是pattern,基于一个pattern调用sub里边传入的就是子类型的点class对应的这个类类型啊,那这里边我们可以看到这个sub event这个类型啊,就应该是我们当前数据流中类型,比方说是个event,它的一个子类型。那这样的话,本身这个数据类型我们这样去定义是不矛盾的,但是这里呢,对于某一个个体模式筛选出来的数据又有了对应的子类型的要求,这是一个限定子类型的条件。除了这个之外啊,那最简单的当然就是我们前面看到的代码里面做的simple condition了,简单条件,其实我们发现这个simple condition本质上就是一个filter操作,对吧?里边实现的就是一个filter方法啊,那这里边我们可以看到当前这个filter方法会返回一个。
03:17
布尔类型的值,哎,我们说如果当前返回的是true的话,就表示当前的事件是符合匹配规则的,如果返回false的话,那就是不符合匹配规则。如果我们点到源码里边去看一下的话,就会发现当前的simple condition。他其实是继承自。Condition可迭代条件,另外呢,还实现了filter function接口,所以我们说它本质上就可以看成是一个filter function,果然是没错的啊,它里面关键要实现的这一个。方法,抽象方法,也就是filter,我们可以把它看成一个进行过滤的这样的一个条件。
04:02
这是简单条件的定义啊,那基于这个简单条件我们也看到了,对应的还有一个所谓的可迭代条件啊,迭代条件ter,那简单条件呢,区别就在于简单条件只能基于当前的事件进行一个判断,它的逻辑当然就比较简单了,就是一个filter function嘛,那在实际应用过程当中呢,我们可能不仅仅要基于当前的事件。可能还要考察之前的一些事件,然后判断要不要接收当前的事件啊,那所以这种需要依靠之前的事件来做判断的条件,叫做迭代条件。啊,那这个迭代条件就是刚才我们看到的啊,Simple condition继承字的这个condition啊,那这里面其实如果我们仔细观察的话,会发现本身这里的方法调用它要求传入的参数类型就是一个迭代条件,那当然这里simple condition是继承自迭代条件的嘛,所以直接传一个simple condition也是没有问题的。
05:10
而这里的condition啊,迭代条件,简单条件最大的区别在哪里呢?我们看到里边它同样也是有一个抽象方法filter,必须要实现这样一个filter方法,那这个filter方法有什么区别呢?我们看除了当前的数据之外,还多了一个。Ctx作为参数传入。那这里的CX很明显就是一个上下了啊,那当然这个上也是在当前里边去出来的,这里这个上下文呢,继承字time context,这个time context其实就是包含了时间相关信息的这样的一个上下文的接口啊,所以我们看到这里边可以拿到当前的时间戳,可以拿到当前的current processing啊,理论上时间戳的话,我们可以认为就类似于可以只是当前的事件时间啊,那这样的话就相当于可以获取到当前的一些时间信息。
06:12
那。对于当前这个condition而言,既然多了这样一个上下文,哎,那我们看到在这个里边还有一个什么样的方法呢?它有一个get events for pattern这样一个方法,这里边传一个string类型的name,很明显就是针对我们在。Patternon定义过程当中指定的这个name,指定的每一个个体模式的名称,然后可以去获取到对应的事件,我们看到得到的是一个T类型啊,那可迭代类型嘛,那类似于之前我们看到map里边的那个list。所以得到了对应的这些事件,接下来我们就可以基于之前已经捕获到的某些事件来判断要不要。
07:08
Filter掉当前的这个数据了。这一部分看起来有一点抽象,我们可以结合一个具体的事例来简单的分析一下这个迭代条件到底是怎么样去用的。比如说之前这个简单条件的话,我们可以想到啊,假如说我们这里边传一个value user.a啊,那其实这个就表示当前我们当前这个事件啊,里边有一个user字段啊,那我要求这个user用户必须是以A开头的啊,那。如果是迭代条件的话,我们看看它可以怎么用迭代条件。首先前面我们定义了一个middle,这是一个当前的pattern啊,某一个pattern个体模式,然后接下来呢,它定义了一个点,One or more,也就是说当前这个个体模式可以一次或者多次匹配。啊,那当前这个体模式可能就可以匹配多个事件了,然后接下来点where指定条件,给了一个迭代条件。
08:07
这里边的event呢,跟我们前面啊,在data API那一部分里边定义出来的那个port类不太一样啊,我们只知道这是一个事件类型就可以了,然后接下来我们看一下,这里边必须要去重写这个filter方法,我们看一下怎么样去处理呢?那首先我们还可以判断一下当前这个user是否以A开头,跟之前的简单条件是完全一样的,假如不以A开头的话,直接返回false。那如果以A开头,就直接返回处吗?不再那么简单了。以A开头,也有可能不返回处,以A开头的话,还要判断一个什么呢?这里边我们要再判断一个当前的amount啊,那就是当前这个event里边除了user,除了用户之外,可能还有一个数量这样一个字段,那我们要考察这个数量,当前的这个数量呢,首先我们定义了一个sum,就等于当前的这个数量,然后在这个基础上。
09:04
叠加,叠加什么呢?我们看到这里边是便利了。Ctx上下文当中gets for。诶,那我们看的这个middle,当前我们这个变量定义的叫middle,那之前对应的那一个名称,当前个体模式的名称也叫middle,那所以这里边获取出来的是什么呢。就是当前这个one or more已经捕获到的之前所有的事件。那当前捕获到了所有事件便利,然后把它的amount都拿出来做了一个叠加判断,如果说当前的总和amount总和小于100的话。就return,那如果要大于等于100超过这个上限啊,那就相当于不能匹配成功了,所以我们会看到当前如果是one or more的话,我们会想到这是不是就是无限匹配下去呢?
10:02
哎,如果说我们没有任何的限制条件的话,它确实是后面有多少匹配多少。那往往我们在实际应用的过程当中不能无限匹配下去,没有必要啊,所以用什么方法可以对它进行限制呢?在当前的迭代条件里边,这里边可以根据它的amount的总和来做一个限制,也就是说我们现在的匹配条件其实是。事件当前的事件,它的user用户必须是以A开头,这是一个条件,另外呢啊,当前循环匹配到的所有的事件,它的数量总和amount总和应该要小于100,如果超过100的话。弯帽也不再继续匹配。啊,这就是所谓的迭代条件啊,那这个迭代条件我们看到它因为可以获取到已经匹配到的所有事件嘛,那另外呢,如果自身又是循环模式的话,还可以捕获自身之前已经匹配到的所有数据,所以我们看到这个功能就非常的强大,那利用它就可以实现非常复杂的逻辑判断和对应复杂事件处理的这样的一个需求。
11:16
除了简单条件和迭代条件之外呢,啊,那另外条件还可以组合起来,这就是所谓的组合条件啊,因为我们想到假如说一个个体模式啊,它的条件很多,不仅仅只有一个,哎,我们这里面判断的这个条件,这就只有一个。布尔类型的表达式嘛,那假如有多个条件的话,那就应该有多个波尔判断啊,那如果多个条件怎么办呢?呃,一个简单的想法是,我们可以把这个布尔表达式做一个逻辑与与或非的组合,那另外呢,还可以像前面我们在这一个事例里边看到的啊,可以各种if else,根据不同的条件去做判断组合,这些肯定是可以做到的,但是这样呢,代码会变得比较臃肿,可读性也会降低。
12:07
那更好的方式呢,就是独立定义每一个布尔类型表达式的值,然后作为我们当前的一个条件,然后把不同的当前个体模式的不同条件。叠加在外边继续调用点where组合起来。啊,那所以就是点位后面如果再接一个点位,这也是可行的,它们的组合方式其实就是一个逻辑与的关系啊,因为我们知道这里边其实就相当于一个filter,一个呃,就是方式一个过滤嘛,所以你过滤了一道之后再过滤,用另外一个条件再过滤一道,显然过滤出来的就是同时符合这两个条件的数据了。啊,那所以直接v.V得到的就是一个逻辑与的条件组合,那如果要是逻辑或怎么办呢?啊,逻辑或也简单,我们看到可以直接调一个点or方法啊,那这个就是一个逻辑或的组合关系。
13:07
另外就是关于前面我们提到的sub type也可以跟当前的where条件组合起来,然后呃,相当于是一个逻辑与的关系,就是要求必须符合当前的子类型限定,另外呢,还要符合当前wherer给定的这个条件限制。所有的这些都可以组合在一起来用。除了这些条件之外,另外还有一类比较特殊的条件叫做。终止。对于,特别是对于这个循环模式而言,我们还可以去指定一个终止条件,而且是往往会推荐去定义这样一个终止条件,它主要就是表示遇到某个特定的事件的时候,在这个终止条件后面跟的是一个特定的条件,特定的事件,遇到这个事件的时候,当前模式就不再继续循环下去了,不再找了。
14:04
哎,那所以这里边我们终止条件的定义呢,它是调一个点NQ方法,哎,那这里面我们可以看到就是如果要直接点NQ的话,里边传入的还是一个迭代条件condition,所以它本质上这里边调用的过程跟直接点where或者点or是一样的,那它的。简单来看的话,就有点儿像是一个曲飞啊啊这样一个逻辑,飞的这样的一个状态,那它主要呢,就是用来终止我们具有循环条件的个体模式的这种无穷无尽的判断和等待。那我们就可以想到,在什么样的循环模式下,我们就一定要用这样的NQ来进行终止呢?这里注意一下,终止条件只与one or more或者one or more optional结合使用。因为在这种循环模式下面,其实我们知道啊,你是one more嘛,后边是不知道的,不知道到底有多少,所以如果前面有匹配的话,我们就只好一直缓存起来,一直在等后面到底还有没有新的,那我们知道这个等待是无穷无尽的,流数据是无穷无尽的,那当前的等待也就是无穷无尽。
15:22
所以如果一直等下去的话,最终这个状态越来越多,会耗尽我们的内存。所以必须为这种循环模式设定一个终止条件,那就是用NQ来指定。符合这个条件的时候,我们就可以清空状态,释放内存。这就是关于个体模式当中条件的各种用法。
我来说两句