0

In my Spring Boot / Spring Data MongoDB project I have a following POJO:

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

    private String id;

    private DecisionAnalysisRequest decisionAnalysisRequest;

    private DecisionMatrixPageResponse decisionMatrixPage;

    private Date createDate;

    private HttpRequestData httpRequestData;

...

}

where 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;

...

}

I need to lookup DecisionAnalysis documents by DecisionAnalysisRequest so I have created a Spring Data MongoDB repository with the following method:

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

    DecisionAnalysis findByDecisionAnalysisRequest(DecisionAnalysisRequest decisionAnalysisRequest);

}

Right now this method only work when filterQueries is null. But when filterQueries is not null the method continuously returns no results.

filterQueries is an array of composite objects, for example:

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

What am I doing wrong and how do I adjust my code in order to properly look up DecisionAnalysis documents by DecisionAnalysisRequest even when the filterQueries contains data.

UPDATE

This is a sample DecisionAnalysisRequest document that I'm going to use as a key(information inside of this document varies each time per user selected on 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
         ]
      }
   ]
}
9
  • that is because it will try to compare the Object in mongo with the object you have passed as argument to the method using equals method. If none present in your class, it will take the default Equals method and will fail because it does a deep compare. Try defining a equals(and ofcourse hashcode) methog in your DecisionAnalysisRequest class and not include filterQueries in your equals method definition.(needless to say, you should not include that in your hashcode as well) Commented May 14, 2017 at 17:16
  • Another solution could be to include a unique field like id in your DecisionAnalysisRequest class and query using that id. If your new Unique field is called id, Then your repositoryMethod will look something like this findByDecisionAnalysisRequest_Id(...) Commented May 14, 2017 at 17:19
  • @pvpkiran thanks for your answer. Why do I need to not include filterQueries in my equals/hashcode methods ? filterQueries is an important part of the the uniqueness of DecisionAnalysisRequest object. Also, I can't use any surrogate ID fields and according to my business logic the key is DecisionAnalysisRequest itself with all of the data inside(including filterQueries as well) Commented May 14, 2017 at 17:26
  • of course you can use. Then in that case you should a deep comparision of every sub field Commented May 14, 2017 at 17:28
  • I have already tried this and it doesn't work for some reason.. Commented May 14, 2017 at 17:41

1 Answer 1

1

The query is run on server side, so you have to look into performance from server stand point of view.

You'll hit the 16MB memory limit for document continuous data growth.

You've to use dot notation to reach to filterQueries embedded doc for comparison.

Below example if you like to match one of the filters.

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

The reason you dont get the response as your comparing the input DecisionAnalysisRequest against the database DecisionAnalysisRequestwhich has more filterQueries.

You should look into comparing criteria on the fields on the document/embedded document/embedded array oppose to compare the whole document/embedded document/embedded array.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for your answer, but I need to find DecisionAnalysis by DecisionAnalysisRequest object and not by the BasicQuery. filterQueries is only a part of DecisionAnalysisRequest
Np. Okay then you need to pass the whole document with same no of fields, order and values. How would you think it should work on mongodb side if you are only including part of filterQueries in the query ? Spring is essentially trying to convert your input to equivalent mongo query.I'm just trying to understand your use case.
I'm not including only filterQueries.. I have showed filterQueries only as example. I use the full DecisionAnalysisRequest(also with filterQueries) for DecisionAnalysis look up. Also, when I say that the data will growth - I mean I'll have a many millions of DecisionAnalysis documents stored at MongoDB but no one of these documents will hit the 16 mb limit.
Okay. Try debug to see what query is generated when you send complete DecisionAnalysisRequest, just as shown in your update. This should work in equals comparison the way you have. You can create index on DecisionAnalysisRequest to begin with, but I think it would be efficient if you can identify queryable fields as oppose to full document match.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.