【问题标题】:Selecting data from MongoDB where K of N criterias are met从满足 N 个条件中的 K 个的 MongoDB 中选择数据
【发布时间】:2017-02-03 23:58:03
【问题描述】:

我有四个字段的文档:A、B、C、D 现在我需要找到至少三个字段匹配的文档。例如:

查询:A=a, B=b, C=c, D=d

退回的文件:

  1. a,b,c,d(四人中的四人相遇)
  2. a,b,c(四人中的三人相遇)
  3. a,b,d(四人中的另外三人相遇)
  4. a,c,d(四人中的另外三人相遇)
  5. b,c,d(四人中的另外三人相遇)

到目前为止,我创建了类似的东西:

`(A=a AND B=b AND C=c)
 OR (A=a AND B=b AND D=d)
 OR (A=a AND C=c AND D=d)
 OR (B=b AND C=c AND D=d)`

但这很丑陋且容易出错。

有没有更好的方法来实现它?此外,查询性能也很重要。

我正在使用 Spring Data,但我相信这没关系。我当前的代码:

    Criteria c = new Criteria();

    Criteria ca = Criteria.where("A").is(doc.getA());
    Criteria cb = Criteria.where("B").is(doc.getB());
    Criteria cc = Criteria.where("C").is(doc.getC());
    Criteria cd = Criteria.where("D").is(doc.getD());

    c.orOperator(
            new Criteria().andOperator(ca,cb,cc),
            new Criteria().andOperator(ca,cb,cd),
            new Criteria().andOperator(ca,cc,cd),
            new Criteria().andOperator(cb,cc,cd)
    );
    Query query = new Query(c);

    return operations.find(query, Document.class, "documents");

【问题讨论】:

    标签: mongodb mongodb-query spring-data-mongodb mongodb-java


    【解决方案1】:

    目前在 MongoDB 中,我们无法直接执行此操作,因为我们没有任何支持查询参数排列/组合的功能。

    但我们可以通过将条件分成几部分来简化查询。

    使用Aggregation管道

    $projectwith records (A=a AND B=b) --> This will give the records which are having two conditions matching.(我们的目标是找到在给定条件下匹配 3 out of 4 或 4 out of 4 的记录)`

    Next in the pipeline use OR condition (C=c OR D=d) to  find the final set of records which yields our expected result.
    

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      按照您的方式,您必须在查询中进行所有排列。您可以使用聚合框架来执行此操作,而无需置换所有组合。它对于任何K 都足够通用。缺点是我认为你需要 Mongodb 3.2+,而且 Spring Data 还不支持这些操作:$filter$concatArrays

      但是使用 java 驱动程序可以很容易地做到这一点。

      [  
         {  
            $project:{  
               totalMatched:{  
                  $size:{  
                     $filter:{  
                        input:{  
                           $concatArrays:[ ["$A"], ["$B"], ["$C"],["$D"]]
                        },
                        as:"attr",
                        cond:{  
                           $eq:["$$attr","a"]
                        }
                     }
                  }
               }
            }
         },
         {  
            $match:{  
               totalMatched:{ $gte:3 }
            }
         }
      ]
      

      您所做的只是将需要检查的所有字段的值连接到一个数组中。然后选择与您正在寻找的值(或您想要的任何条件)相等的那些元素的子集,最后获取每个文档的该数组的大小。

      现在您需要做的就是$match 大小大于或等于您想要的大小的文档。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-10
        • 2020-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多