MongoDB Aggregate, массивы и логические операции - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь выполнить операции между двумя массивами с MongoDB Aggregate.

Допустим, первый массив равен

files = [["1.txt", "2.txt", "4.txt"], [ "1.txt", "2.txt"],  [ "1.txt" ]]. 

, а другой -

operators = ["=",  "+"]

Как я могу написать код, который берет первые 2 элемента из файлов и один из операторов (скажем, вы связали "+" с $ setIntersection и "=" с $ setUnion) и выполните требуемую операцию. Это должно повторяться до тех пор, пока не останется больше операторов (результат последней операции с новым элементом файлов). Как это может быть достигнуто в MongoDB с помощью агрегатных или других методов?

Я пытался, я действительно пытался и получил это:

.aggregate([{"$match": {"term":{"$in":["1", "10", "100"]}}},
            {"$group": {"_id":"BooleanSearch","files": { "$push": "$docs.d" },"initialSet": { "$first": "$docs.d" }}},
            {"$addFields":{"operators":["=", "+"]}},
            {"$unwind":"$operators"},
            {"$addFields": {"result": {"$reduce": {"input": "$files", "initialValue": "$initialSet" ,"in": {"$switch":{"branches": [
                     { case: {"$eq": [ "$operators", "+"]}, then: { "$setIntersection": [ "$$value", "$$this" ]}},
                     { case: {"$eq": [ "$operators", "-"]}, then: { "$setDifference": [ "$$value", "$$this" ]}},
                     { case: {"$eq": [ "$operators", "="]}, then: { "$setUnion": [ "$$value", "$$this" ]}}],
                     default: "Index out of bounds"}}}}}},
            {"$project":{"_id":0,"result":1}}])

Это приводит к выводу:

/* 1 */
{
    "result" : [ 
        "1.txt", 
        "2.txt", 
        "4.txt"
    ]
}

/* 2 */
{
    "result" : [ 
        "1.txt"
    ]
}

То, что все это делает: для каждого оператора вы выполняете операцию со всем массивом, что не является тем, что я намеревался, и это дает вам результат (все массивы с одной и той же операцией). Как можно работать с элементами массива, а не со всем массивом?

Желаемый результат будет

{ "result" : [ "1.txt" ] } 

Он получается путем объединения (=) между первыми 2 элементами файлов, за которым следует пересечение (+) результата с последним элементом файлов.

...