使用Spring Mongo在聚合操作中为ConditionalOperators传递动态值

huangapple go评论104阅读模式
英文:

Passing dynamic values for ConditionalOperators when Aggregating in Spring Mongo

问题

I'm new to mongo aggregation and I want to check whether following is possible in spring mongo. I'm aware we can write conditions as given,

    ConditionalOperators.Cond cond = when(Criteria.where("status").is("PRESENT")).then(1)
                    .otherwise(when(Criteria.where("status").is("ABSENT")).then(2)
                    .otherwise(100)); 

Given that I have a map with possible condition values, I want to know whether it is possible to pass the values using the map to the condition. 

    Map<String, Integer> dynamicValues = new HashMap<>();
    dynamicValues.put("PRESENT", 1);
    dynamicValues.put("ABSENT", 2);

This is what I have as of now. But it is not working as expected.

  
    List<String> dynamicValues = Arrays.asList("PRESENT", "ABSENT");

    ConditionalOperators.Cond.OtherwiseBuilder operator = ConditionalOperators.when(Criteria.where("status").is(dynamicValues.get(0))).then(0));
    
    for (String s : dynamicValues) {
        ConditionalOperators.Cond.OtherwiseBuilder shippingDestination = when(Criteria.where("status").is(s)).then(1);
        operator.otherwise(shippingDestination);
    }
    
    return (ConditionalOperators.Cond) operator;

I have hard coded the then value temporarily.
英文:

I'm new to mongo aggregation and I want to check whether following is possible in spring mongo. I'm aware we can write conditions as given,

ConditionalOperators.Cond cond = when(Criteria.where(&quot;status&quot;).is(&quot;PRESENT&quot;)).then(1)
                .otherwise(when(Criteria.where(&quot;status&quot;).is(&quot;ABSENT&quot;)).then(2)
                .otherwise(100)); 

Given that I have map with possible condition values, I want to know whether it is possible to pass the values using the map to the condition.

Map&lt;String, Integer&gt; dynamicValues = new HashMap&lt;&gt;();
dynamicValues.put(&quot;PRESENT&quot;, 1);
dynamicValues.put(&quot;ABSENT&quot;, 2);

This is what I have as of now. But it is not working as expected.

List&lt;String&gt; dynamicValues = Arrays.asList(&quot;PRESENT&quot;, &quot;ABSENT&quot;);

ConditionalOperators.Cond.OtherwiseBuilder operator =  ConditionalOperators.when(Criteria.where(&quot;status&quot;).is(dynamicValues.get(0))).then(0));

        for (String s : dynamicValues) {
            ConditionalOperators.Cond.OtherwiseBuilder shippingDestination = when(Criteria.where(&quot;status&quot;).is(s)).then(1);
            operator.otherwise(shippingDestination);
        }

        return (ConditionalOperators.Cond) operator;

I have hard coded the then value temporary.

答案1

得分: 1

我找到了一种方法来动态添加条件,而不是硬编码数值,使用以下代码片段。将其发布出来,以便对他人有所帮助。如果有更好的方法,请告诉我。

private ConditionalOperators.Cond buildCondition() {
    List<String> elements = Arrays.asList("ABSENT", "PRESENT");
    ConditionalOperators.Cond previousCondition = null;
    ConditionalOperators.Cond resultCondition = null;

    //#### 无法在没有否则条件的情况下构建条件,因此以相反的顺序构建条件。
    ListIterator<String> listIterator = elements.listIterator(elements.size());

    while (listIterator.hasPrevious()) {
        ConditionalOperators.Cond currentCondition;
        boolean isLastElement = !listIterator.hasNext();
        String currentElement = listIterator.previous();
        // 使用动态目标和优先级创建否则条件。
        ConditionalOperators.Cond.OtherwiseBuilder otherWiseCondition = when(Criteria.where("status")
                .is(currentElement))
                .then(<添加真实值>);

        if (isLastElement) {
            // 如果是最后一个元素,则添加 else 条件。
            currentCondition = otherWiseCondition.otherwise(<else 条件值>);
        } else {
            // 将上一个元素添加为否则条件。
            currentCondition = otherWiseCondition.otherwise(previousCondition);
        }

        resultCondition = currentCondition;
        previousCondition = currentCondition;
    }

    return resultCondition;
}

注意:上述代码片段中的 <add the real value><else condition value> 部分需要根据实际情况进行替换。

英文:

I figured out a way to add the conditions dynamically without hardcoding the values using the following code snippet. Posting it so that it would be useful to someone else. Let me know if there is a better way to do this.

 private ConditionalOperators.Cond buildCondition() {
    List&lt;String&gt; elements = Arrays.asList(&quot;ABSENT&quot;, &quot;PRESENT&quot;);
    ConditionalOperators.Cond previousCondition = null;
    ConditionalOperators.Cond resultCondition = null;

    //#### Conditions cannot be built without the otherwise condition, therefore, build conditions in reverse.
    ListIterator&lt;String&gt; listIterator = elements.listIterator(elements.size());

    while (listIterator.hasPrevious()) {
        ConditionalOperators.Cond currentCondition;
        boolean isLastElement = !listIterator.hasNext();
        String currentElement = listIterator.previous();
        // create the otherwise condition with the dynamic destination and priority.
        ConditionalOperators.Cond.OtherwiseBuilder otherWiseCondition = when(Criteria.where(&quot;status&quot;)
                .is(currentElement))
                .then(&lt;add the real value&gt;);

        if (isLastElement) {
            // if last element, add the else condition.
            currentCondition = otherWiseCondition.otherwise(&lt;else condition value&gt;);
        } else {
            //add the previous element as the otherwise condition.
            currentCondition = otherWiseCondition.otherwise(previousCondition);
        }

        resultCondition = currentCondition;
        previousCondition = currentCondition;
    }

    return resultCondition;
}

huangapple
  • 本文由 发表于 2020年9月9日 09:10:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63803429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定