从solr结果集中取数据,取到了结果集,但是结果集是一个map,而我想要得到的是一个对象,怎么处理呢?我先后尝试了三种方式:
以下是获取的源数据:
SolrDocument[{id=25157561, productId=000000000108292291, product={"name":"鸭鸭 2013新潮90绒短款轻薄羽绒服女正品清仓 时尚春秋外套B-360 柠檬黄 170/92A","oldId":"19999729","type":"0","brandId":"000153467","brandName":"鸭鸭","labelPaste":"null","imageCount":5,"firstCategoryId":"361003","secondCategoryId":"161007","thirdCategoryId":"346882","firstCategoryName":"服装鞋帽","secondCategoryName":"女装","thirdCategoryName":"羽绒服","purchaseCategory":"R9001206","id":"000000000108292291","groupId":"284049","color":"柠檬黄","version":"170/92A"}, showOrderFlag=0, userId=6000654740, user={"province":"","birthday":"","constellation":"","id":"6000654740","nickName":"112***1","gender":"","typeId":"1","imageUrl":"http://image.suning.cn/uimg/cmf/cust_headpic/0000000000_01_60x60.jpg","levelId":"161000000020","levelName":"银卡会员"}, storeFlag=0, store={}, againReviewFlag=0, title=, content=骨灰盒江景房, contentLength=6, labels=[], score=1, anonymousFlag=0, bestFlag=0, sort=0, status=0, createDate=Tue Aug 27 17:02:43 CST 2013, publishIp=10.19.95.189, publishDeviceId=1, usefulVoteCount=0, replyCount=0}]
方案一:solrDocument中提供了一个获取每个field对应值的方法,使用此方法获取所有的field对应的值,set到类中:
private List<ReviewFieldDTO> setReviewData(SolrDocumentList list) { List<ReviewFieldDTO> datas = new ArrayList<ReviewFieldDTO>(); String jsonStr = ""; ReviewFieldDTO review = null; for (SolrDocument solrDocument : list) { review = new ReviewFieldDTO(); review.setId((Long)solrDocument.getFieldValue("id")); review.setProduct(solrDocument.getFieldValue("product").toString()); review.setOrderDate((Date)solrDocument.getFieldValue("orderDate")); ... datas.add(review); } return datas; }
这样做的缺点:
1、我的类中有20-30个属性,就要需要二三十此,代码相当低级,可读性很差
2、如果solr中没有一个field对应的值为空,就会报异常,这样每一个solrDocument.getFieldValue方法都要try-catch,我想这样写肯定不行,能不能直接将solrDocument变成我要的ReviewFieldDTO类呢,经过代码编写,我使用了第二种方案:
方案二:我使用了BeanUtils工具+反射,通过反射,获取solrDocument中的所有key和value,然后利用BeanUtils.setProperty(bean, name, value);方法,给ReviewFieldDTO设置属性,这样也有缺点,就是反射过程中容易出现异常,另外更严重的是此方法对Date类型的属性不能处理,而ReviewFieldDTO中有Date类型的属性,如果非要使用这种方案,就要写date类型的转换类,无疑增加了代码量,我只能放弃这种方案。
方案三:这是最后想到的一种方案,因为拿到上面的map值后,感觉跟json很像,但是又不是json格式,一直在做的是将map直接转换为对像,忘记了可以使用json作为中间变量,所以方案三你们应该是想到了:
private List<ReviewFieldDTO> setReviewData(SolrDocumentList list) { List<ReviewFieldDTO> datas = new ArrayList<ReviewFieldDTO>(); String jsonStr = ""; ReviewFieldDTO review = null; for (SolrDocument solrDocument : list) { jsonStr = getJson(solrDocument); review = new ReviewFieldDTO(); review = gson.fromJson(jsonStr, ReviewFieldDTO.class); datas.add(review); } return datas; }
就是先将solrDocument类转换为json,然后再将此json转换为我要的ReviewFieldDTO类,太爽了吧,之前太逗比了吧 ,所以有时候设计思路很重要,不一定非要直接将map转成对象,可以使用中间变量。OK,先这么多吧
下面一楼一位大哥给的评论太爽了,之前工作都是废的啊,原来solr中提供了将solrDcoument转换为类的API,哎,道行差太远啊。。。
private List<ReviewFieldDTO> setReviewData(SolrDocumentList list) { DocumentObjectBinder binder = new DocumentObjectBinder(); List<ReviewFieldDTO> reviews = binder.getBeans(ReviewFieldDTO.class, list); return reviews; }
这下好了,感谢那位大拿!!!