Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
890 views
in Technique[技术] by (71.8m points)

node.js - Call function inside mongodb's aggregate?

Collection:

[
    { _id: "Foo", flag1: false, flag2: true, flag3: false },
    { _id: "Bar", flag1: true, flag2: false, flag3: true }
]

My question is, is it possible to call a method inside aggregate query?

aggregate({
    $project: {
        '_id': 1,
        'status' MyService.getStatus($flag1, $flag2, $flag3)
    }
});

If it is possible, what is the syntax of it? Result:

[
    { _id: "Foo", status: 'ok' },
    { _id: "Bar", status: 'broken' }
]

In my real world application I have 10 boolean flags per document. If the user gets this documents I would like to convert the flags and give them a meaning (for the user). E.g. consider a document represents a tire.

flag1 = true means tire have good pressure, false means low pressure
flag2 = true means depth of tire profile is good, false means little profile
and so on

So in summary I would like to say a tire is OK if

 flag1, flag2 are true and flag3 is false

and a tire needs to be replaced (BROKEN or REPLACE) when

flag1, flag2 are false and flag3 is true

When a document is returned to the user the flags should be removed. Instead we have the status field that says the tire is either OK or BROKEN.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

External functions don't work with the aggregation framework. Everything is parsed to BSON on input, so no JavaScript or anything else is allowed. This is all basically processed from BSON "operator" definition to native C++ code implementation so it is really fast.

What this comes down to is "converting" your expected logic to what the aggregation framework can process. There are in fact "logical" operators such as $or and $and that work in this context:

db.collection.aggregate([
    { "$project": {
       "_id": 1,
       "status": {
           "$cond": [
               { "$or": [
                   // Your first set of rules requires "false" for "flag1" or 
                   // "flag2" and "true" for "flag3"
                   { "$and": [
                       { "$not": [
                           { "$or": [ "$flag1", "$flag2" ] },
                       ]},
                       "$flag3"
                   ]},
                   // Your second set of rules requires "true" for "flag1" or 
                   // "flag2" and "false" for "flag3"
                   { "$and": [
                       { "$or": [ "$flag1", "$flag2" ] },
                       { "$not": [ "$flag3" ] }
                   ]},
               ]},
               "ok",
               "broken"
           ]
       }
    }}
])

So no external functions, just implement the logic with the operators that the aggregation framework supplies. In addition to the basic logical implementations there is $not to "reverse" the ligic and $cond which acts as a "ternary" in order to provide a different result from true/false evaluation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...