我正在使用教程(https://spring.io/guides/tutorials/data/2/)学习Spring Data MongoDB。 在本教程中,cost的类型是BigDecimal,如下所示,它在MongoDB中存储为“字符串”。 所以,当我试图通过成本字段按升序排序得到排序结果时,我得到了错误的结果。
我发现使用BigDecimal类是计算的最佳方法。 但是,如果我使用MongoDB中的Spring Data MongoDB将数字保存为BigDecimal类型, 它将保存为字符串类型 我将得到一个错误的排序结果,如本教程。
为了精确起见,我能做些什么来获得正确的数字排序结果? 你能帮我解决这个问题吗? 非常感谢你提前。
例如,
1> MenuItem类
@Document(collection = "menu")
public class MenuItem {
@Id
private String id;
@Field("itemName")
@Indexed
private String name;
private BigDecimal cost;
2 - ;创建MenuItem的实例
MenuItem item = new MenuItem();
item.setDescription("Peanutty Noodles, perfect for every occasion.");
item.setName("Yummy Noodles");
item.setCost(new BigDecimal("52.99"));
MenuItem item = new MenuItem();
item.setDescription("Rice, Egg Fried");
item.setName("Yummy Rice");
item.setCost(new BigDecimal("211.99"));
3>排序结果
db.menu.find()排序({成本:1})。
{“_ id”:ObjectId(“53e982f0300475a4fbab8c32”),“_ class”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“Yummy Rice”,“description”:“Rice,Egg Fried” ,“成分”:[{“name”:“Egg”,“description”:“Chicken Eggs”},{“name”:“Rice”,“description”:“Straight White Rice”}],“cost”: “211.99”,“minutesToPrepare”:0}
{“_ id”:ObjectId(“53e982f0300475a4fbab8c33”),“_ class”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“Yummy Rice”,“description”:“Rice,Egg Fried” ,“成分”:[{“name”:“Egg”,“description”:“Chicken Eggs”},{“name”:“Rice”,“description”:“Straight White Rice”}],“cost”: “211.99”,“minutesToPrepare”:0}
{“_ id”:ObjectId(“53e982f0300475a4fbab8c2f”),“_ class”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“Yummy Noodles”,“description”:“Peanutty Noodles,非常适合每个场合。“,”成分“:[{”name“:”Peanuts“,”description“:”A Nut“},{”name“:”Egg“,”description“:”用于面条“}, {“name”:“Noodles”,“description”:“酥脆,可爱的面条”},“费用”:“52.99”,“minutesToPrepare”:0}
{“_ id”:ObjectId(“53e982f0300475a4fbab8c30”),“_ class”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“Yummy Noodles”,“description”:“Peanutty Noodles,非常适合每个场合。“,”成分“:[{”name“:”Peanuts“,”description“:”A Nut“},{”name“:”Egg“,”description“:”用于面条“}, {“name”:“Noodles”,“description”:“酥脆,可爱的面条”},“费用”:“52.99”,“minutesToPrepare”:0}
{“_ id”:ObjectId(“53e982f0300475a4fbab8c31”),“_ class”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“Yummy Noodles”,“description”:“Peanutty Noodles,非常适合每个场合。“,”成分“:[{”name“:”Egg“,”description“:”用于面条“},{”name“:”Peanuts“,”description“:”A Nut“}, {“name”:“Noodles”,“description”:“酥脆,可爱的面条”},“费用”:“52.99”,“minutesToPrepare”:0}
答案 0 :(得分:1)
不幸的是,BigDecimal
本身就是MongoDB的not supported。这就是我们默认将其转换为String
的原因。
对于更多的数字处理,特别是在处理价格等时,我们通常建议改为存储双打,并将它们直接转换为BigDecimal
s用于域对象中的算术运算。
答案 1 :(得分:1)
如果您正在处理Money - 并且“cost”看起来像那样 - 那么在代码中使用Money类。钱将带有金额和货币。 Money有方法可以将数量作为BigDecimal获取等等。在MongoDB中坚持这样丰富的形状:
{cost:{amt:21199,ccode:“USD”}}
所有相同货币的数字操作(eq,gt,lt等)都能正常工作。 而且你无论如何都无法在数据库中进行交叉货币比较,因为汇率是动态的。
答案 2 :(得分:1)
自版本 3.4 以来,MongoDB已添加对" BigDecimal"的支持。按新的十进制数据类型(decimal128)。但是,默认情况下,spring数据仍然将Java class Login extends React.Component {
login(e) {
e.preventDefault();
var user = '';
var pass = '';
user = this.state.username;
pass = this.state.password;
this.authenticate(user, pass);
return;
}
async authenticate(username, password) {
let _this = this;
Api.login(username, password)
.then(async response => {await response.json()})
.then(async response => {
//My code
});
}
render() {
let { username, password } = this.state;
return (
<View >
<TextField
label='username'
value={username}
autoCapitalize= 'none'
onChangeText={ (username) => this.setState({ username }) }
/>
<TextField
label='password'
value={password}
secureTextEntry autoCapitalize= 'none'
onChangeText={ (password) => this.setState({ password }) }
style={{marginBottom: 10}}
/>
<TouchableOpacity style={styles.loginButtons} onPress={(e) =>
this.login(e)}>
<Text style={styles.buttonText}> Login </Text>
</TouchableOpacity>
</View>
);
}
}
映射到MongoDB login(username, password) {
let url = '/api/sessions';
return fetch(BASE_URL + url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user: {
email: username,
password: password
}
})
});}
(我想这是为了向后兼容)。好消息是可以通过在spring boot应用程序中注入BigDecimal
来简单地覆盖默认映射,如下所示:
string
请检查this post for more detailed information and even a complete example。