JSON reverse request: find all requests in the collection matching the object

I am developing a generic subscription system where the user can specify a compound rule during subscription in terms of a MongoDB request or, moreover, a json request. Subscription data is stored in the MongoDB collection. For instance,

{ "userId": 1, "rule": {"p1": "a"} } { "userId": 2, "rule": {"p1": "a", "p2": "b"} } { "userId": 3, "rule": {"p3": {$gt: 3} } } 

Later, when an event occurs in the form of a json object, for example the following, I want to find all the user rules that should be executed in this case:

 {"p1": "a", "p3": 4} 

The above event must comply with the rules specified in examples 1 and 3 of the user. The event object should not be stored in MongoDB.

Although I can probably fulfill this requirement by writing a loop at the application level. For efficiency, I really want to implement it at the db level, it is advisable to allow distributed (plastered) execution due to volume and latency requirements.

Is it possible? Any help is appreciated. In fact, I am open to other NOSQL dbs, while a dynamic event schema is supported, and there is a way to specify a compound rule.

+5
source share
3 answers

What you are trying to achieve is not possible, at least in MongoDB.

If you talk about how the query mechanism works, you will realize that this does not have a direct solution.

In high-level terms, the engine will generate a condition object from your query, which will then be evaluated for each document in the set, which will lead to a logical value that determines whether the document belongs to the result set or not. In your case, you want to do the opposite, you want to create a condition object based on the document, and then apply it to something (for example, to the object) that you give it.

Even if it was possible, the cost of doing this in the database would be too high, because you would need to compile the expression function for each object and execute it, and there would be no way to optimize the execution of the query. It is more reasonable to actually do this outside the database, where you could have expression functions already created.

+7
source

You cannot store "Query Matching Operators" in the mongo database, but you can do this:

 { "userId": 1, "rule": {"p1": "a"} } { "userId": 2, "rule": {"p1": "a", "p2": "b"} } { "userId": 3, "rule": {"p3": {"value": 3, "operator":"gt"} } } 

You store the value of AND OPERATOR in string form, and you can make this request:

 db.test.find({"rule.p3.comparator":"gt", "rule.p3.value":{$lt:4}}) 

Note that if your " gt operator " , you must use $ lt (the opposite comparison operator) in the request

Your complete example looks something like this:

 db.test.find({$or:[{"rule.p3.comparator":"gt", "rule.p3.value":{$lt:4}}, {"rule.p1":"a"}]}) 

This query matches userId 1 and 3 as you want

+3
source

Update: The following solution does not work. The problem with mongodb is that it does not use NodeJs to run javascript with decreasing map size and does not support any package manager. Therefore, it is difficult to use any third-party libraries.

My own proposed solution , which is not confirmed :

  • Compose a query matching json-query syntax

  • upon evt arrival evt call the mapReduce MongoDB function in the custom rule collection to call jsonQuery in mapper

      var jsonQuery = require('json-query') var mapper = function(evt) { function map() { if(jsonQuery(this.rule, {data: evt}){ emit(this.userId); } } return map; }; db.userRules.mapReduce(mapper(evt), ...); 

The reason for making a query in json-query syntax instead of MongoDB query syntax is only json-query offers the jsonQuery method, which tries to map one rule to one object. For the above code to meet these requirements, the following assumptions must be met:

  • MongoDB can do mapReduce on distributed nodes
  • In mapReduce I can use an external library such as json-query , which means that the library code should be distributed to all MongoDB nodes, possibly as a result of closing.
+1
source

All Articles