【问题标题】:Spring Data MongoDB get document by inner objectSpring Data MongoDB 通过内部对象获取文档
【发布时间】:2017-05-14 07:54:53
【问题描述】:

在我的 Spring Boot / Spring Data MongoDB 项目中,我有以下 POJO:

@Document(collection = "decision_analysis")
public class DecisionAnalysis {

    private String id;

    private DecisionAnalysisRequest decisionAnalysisRequest;

    private DecisionMatrixPageResponse decisionMatrixPage;

    private Date createDate;

    private HttpRequestData httpRequestData;

...

}

DecisionAnalysisRequest:

public class DecisionAnalysisRequest implements Serializable {

    private static final long serialVersionUID = 1493180175756424789L;

    private String decisionNameFilterPattern;

    private Set<BaseQuery> filterQueries;

    private Set<Long> sortCriteriaIds;

    private String sortWeightCriteriaDirection;

    private String sortTotalVotesCriteriaDirection;

    private Map<String, Double> sortCriteriaCoefficients;

    private Long sortCharacteristicId;

...

}

我需要通过DecisionAnalysisRequest 查找DecisionAnalysis 文档,因此我使用以下方法创建了一个Spring Data MongoDB 存储库:

@Repository
public interface DecisionAnalysisRepository extends MongoRepository<DecisionAnalysis, String> {

    DecisionAnalysis findByDecisionAnalysisRequest(DecisionAnalysisRequest decisionAnalysisRequest);

}

目前此方法仅在filterQueries 为空时有效。但是当filterQueries 不为null 时,该方法连续不返回任何结果。

filterQueries是一个复合对象数组,例如:

 "filterQueries":[
      {
         "type":"AnyInQuery",
         "characteristicId":711903,
         "characteristicName":"Body type",
         "value":[
            "Compact"
         ],
         "operator":"OR"
      },
      {
         "type":"RangeQuery",
         "characteristicId":712745,
         "characteristicName":"Sensor photo detectors (megapixels)",
         "value":[
            10,
            53
         ]
      }
   ]

我做错了什么以及如何调整我的代码以便通过DecisionAnalysisRequest 正确查找DecisionAnalysis 文档,即使filterQueries 包含数据。

更新

这是一个示例DecisionAnalysisRequest 文档,我将使用它作为键(此文档中的信息每次在 UI 上选择的每个用户都会有所不同):

{
   "sortCriteriaIds":[
      711882,
      711887,
      711884,
      711899,
      711896,
      711897,
      711890,
      711891,
      711888,
      711889,
      711895,
      711892,
      711893
   ],
   "sortCriteriaCoefficients":{

   },
   "pageNumber":0,
   "pageSize":10,
   "sortWeightCriteriaDirection":"DESC",
   "sortid":null,
   "sortCharacteristicDirection":null,
   "sortDecisionPropertyName":null,
   "sortDecisionPropertyDirection":null,
   "decisionsIds":[

   ],
   "persistent":true,
   "includeChildids":null,
   "excludeChildids":null,
   "filterQueries":[
      {
         "type":"AnyInQuery",
         "characteristicId":711913,
         "characteristicName":"Body material",
         "value":[
            "Aluminium alloy",
            "Brass",
            "Carbon fiber"
         ],
         "operator":"OR"
      },
      {
         "type":"AnyInQuery",
         "characteristicId":711903,
         "characteristicName":"Body type",
         "value":[
            "Compact SLR",
            "Compact"
         ],
         "operator":"OR"
      },
      {
         "type":"EqualQuery",
         "characteristicId":712746,
         "characteristicName":"Sensor size",
         "value":"1/1.7\" (7.44 x 5.58 mm)"
      },
      {
         "type":"AnyInQuery",
         "characteristicId":712895,
         "characteristicName":"Color space",
         "value":[
            "Adobe RGB",
            "ECI RGB",
            "Primary color space"
         ],
         "operator":"OR"
      },
      {
         "type":"AnyInQuery",
         "characteristicId":712145,
         "characteristicName":"Other resolutions",
         "value":[
            "1008 x 672",
            "1024 x 1024",
            "1024 x 576"
         ],
         "operator":"OR"
      },
      {
         "type":"AnyInQuery",
         "characteristicId":712738,
         "characteristicName":"Image ratio w:h",
         "value":[
            "1:1",
            "3:2",
            "4:3"
         ],
         "operator":"OR"
      },
      {
         "type":"RangeQuery",
         "characteristicId":712744,
         "characteristicName":"Effective pixels (megapixels)",
         "value":[
            9,
            44
         ]
      },
      {
         "type":"EqualQuery",
         "characteristicId":712901,
         "characteristicName":"Color filter array",
         "value":"RGB color filter array"
      },
      {
         "type":"EqualQuery",
         "characteristicId":712921,
         "characteristicName":"Image stabilization",
         "value":"Sensor-shift"
      },
      {
         "type":"AnyInQuery",
         "characteristicId":712944,
         "characteristicName":"Uncompressed format",
         "value":[
            "No",
            "RAW",
            "TIFF"
         ],
         "operator":"OR"
      },
      {
         "type":"AnyInQuery",
         "characteristicId":712928,
         "characteristicName":"Image parameters",
         "value":[
            "Brightness",
            "Color",
            "Color Space",
            "Color Tone",
            "Contrast"
         ],
         "operator":"OR"
      },
      {
         "type":"RangeQuery",
         "characteristicId":712919,
         "characteristicName":"White balance presets",
         "value":[
            2,
            10
         ]
      },
      {
         "type":"RangeQuery",
         "characteristicId":712917,
         "characteristicName":"Boosted ISO (minimum)",
         "value":[
            1762,
            10741
         ]
      },
      {
         "type":"AnyInQuery",
         "characteristicId":712950,
         "characteristicName":"File format",
         "value":[
            "3FR",
            "AGIF",
            "ARW"
         ],
         "operator":"OR"
      },
      {
         "type":"RangeQuery",
         "characteristicId":712918,
         "characteristicName":"Boosted ISO (maximum)",
         "value":[
            339298,
            2878034
         ]
      },
      {
         "type":"RangeQuery",
         "characteristicId":713340,
         "characteristicName":"Normal focus range (cm)",
         "value":[
            22,
            131
         ]
      },
      {
         "type":"EqualQuery",
         "characteristicId":713343,
         "characteristicName":"Lens mount",
         "value":"Leica M"
      },
      {
         "type":"AnyInQuery",
         "characteristicId":713325,
         "characteristicName":"Autofocus",
         "value":[
            "Center",
            "Continuous",
            "Contrast Detect (sensor)",
            "Face Detection",
            "Live View"
         ],
         "operator":"OR"
      },
      {
         "type":"RangeQuery",
         "characteristicId":713341,
         "characteristicName":"Macro focus range (cm)",
         "value":[
            19,
            75
         ]
      },
      {
         "type":"RangeQuery",
         "characteristicId":713342,
         "characteristicName":"Number of focus points",
         "value":[
            78,
            468
         ]
      },
      {
         "type":"RangeQuery",
         "characteristicId":713388,
         "characteristicName":"Viewfinder resolution (dots)",
         "value":[
            633548,
            3722581
         ]
      },
      {
         "type":"RangeQuery",
         "characteristicId":713386,
         "characteristicName":"Viewfinder coverage %",
         "value":[
            84,
            97
         ]
      }
   ]
}

【问题讨论】:

  • 这是因为它会尝试将 mongo 中的对象与您作为参数传递给使用 equals 方法的方法的对象进行比较。如果你的类中没有,它将采用默认的 Equals 方法并且会失败,因为它会进行深度比较。尝试在您的 DecisionAnalysisRequest 类中定义一个 equals(当然还有哈希码)方法,并且不要在您的 equals 方法定义中包含 filterQueries。(不用说,您也不应该在您的哈希码中包含它)
  • 另一种解决方案可能是在 DecisionAnalysisRequest 类中包含一个唯一字段(如 id)并使用该 id 进行查询。如果您的新 Unique 字段名为 id,那么您的 repositoryMethod 将类似于 findByDecisionAnalysisRequest_Id(...)
  • @pvpkiran 感谢您的回答。为什么我不需要在我的 equals/hashcode 方法中包含 filterQueriesfilterQueriesDecisionAnalysisRequest 对象唯一性的重要组成部分。另外,我不能使用任何代理 ID 字段,根据我的业务逻辑,密钥是 DecisionAnalysisRequest 本身,其中包含所有数据(也包括 filterQueries
  • 当然可以使用。那么在这种情况下,您应该对每个子字段进行深入比较
  • 我已经尝试过了,但由于某种原因它不起作用..

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


【解决方案1】:

查询在服务器端运行,因此您必须从服务器的角度来考虑性能。

您将达到 16MB 内存限制,以实现文档持续数据增长。

您必须使用点符号来访问filterQueries 嵌入式文档进行比较。

如果您想匹配其中一个过滤器,请参考以下示例。

@Query("{decisionAnalysisRequest.filterQueries :?0}")
DecisionAnalysis findByDecisionAnalysisRequest(BasicQuery filter);

您没有得到响应的原因是您将输入DecisionAnalysisRequest 与数据库DecisionAnalysisRequest 进行比较,而数据库DecisionAnalysisRequest 有更多filterQueries

您应该考虑比较文档/嵌入文档/嵌入数组上的字段的标准,以比较整个文档/嵌入文档/嵌入数组。

【讨论】:

  • 感谢您的回答,但我需要通过DecisionAnalysisRequest 对象而不是BasicQuery 找到DecisionAnalysisfilterQueries 只是 DecisionAnalysisRequest 的一部分
  • Np。好的,那么您需要传递具有相同字段、顺序和值的整个文档。如果您只在查询中包含 filterQueries 的一部分,您认为它应该如何在 mongodb 端工作? Spring 本质上是在尝试将您的输入转换为等效的 mongo 查询。我只是想了解您的用例。
  • 我不只包括 filterQueries.. 我只展示了 filterQueries 作为示例。我使用完整的 DecisionAnalysisRequest(也带有 filterQueries)进行 DecisionAnalysis 查找。另外,当我说数据会增长时——我的意思是我将在 MongoDB 中存储数百万个 DecisionAnalysis 文档,但这些文档中没有一个会达到 16 mb 的限制。
  • 好的。尝试调试以查看当您发送完整的DecisionAnalysisRequest 时会生成什么查询,正如您的更新中所示。这应该以您拥有的方式进行平等比较。您可以首先在DecisionAnalysisRequest 上创建索引,但我认为如果您可以将可查询字段识别为与完整文档匹配相反,那将是有效的。
猜你喜欢
  • 1970-01-01
  • 2019-10-10
  • 1970-01-01
  • 2019-10-16
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
相关资源
最近更新 更多