英文:
I need to retrieve MongoDB's object just with filtered's array item
问题
以下是翻译好的内容:
我需要在两个日期范围内从我的MongoDB集合中检索所有文档,并筛选数组中的项目。
这是我的两个文档示例:
{
"_id": ObjectId("5f18fa823406b7000132d097"),
"last_date": "22/07/2020 23:48:32",
"history_dates": [
"22/07/2020 23:48:32",
"22/07/2020 00:18:53",
"23/07/2020 00:49:12",
"23/07/2020 01:19:30"
],
"hostname": "MyHostname1",
"ip": "142.0.111.79",
"component": "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process": "LogonUI.exe",
"date": "23/07/2020 10:26:04"
}
{
"_id": ObjectId("5f18fa823406b7000132d098"),
"last_date": "22/07/2020 23:48:33",
"history_dates": [
"22/07/2020 23:48:33",
"23/07/2020 00:18:53"
],
"hostname": "MyHostName2",
"ip": "142.0.111.54",
"component": "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process": "svchost.exe",
"date": "23/07/2020 10:26:04"
}
我需要在数据库中进行查找(使用Spring Data),以检索相同的对象,但是在收到的两个日期之间筛选“history_dates”数组。
例如,如果我的两个收到的日期是:“23/07/2020”和“24/07/2020”,我希望MongoDB返回以下对象:
{
"_id": ObjectId("5f18fa823406b7000132d097"),
"last_date": "22/07/2020 23:48:32",
"history_dates": [
"23/07/2020 00:49:12",
"23/07/2020 01:19:30"
],
"hostname": "MyHostname1",
"ip": "142.0.111.79",
"component": "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process": "LogonUI.exe",
"date": "23/07/2020 10:26:04"
}
{
"_id": ObjectId("5f18fa823406b7000132d098"),
"last_date": "22/07/2020 23:48:33",
"history_dates": [
"23/07/2020 00:18:53"
],
"hostname": "MyHostName2",
"ip": "142.0.111.54",
"component": "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process": "svchost.exe",
"date": "23/07/2020 10:26:04"
}
我对MongoDB的查询实际上一无所知,我一直在尝试使用Spring Data进行操作,但整周都没有成功。
更新1:
感谢Varman,你知道如何只检索具有非空筛选数组的文档吗?
英文:
I'm needing to retrieve just with two dates, all the documents from my MongoDB's collection, with the filtered items from the array.
This is an example of 2 of my documents;
{
"_id" : ObjectId("5f18fa823406b7000132d097"),
"last_date" : "22/07/2020 23:48:32",
"history_dates" : [
"22/07/2020 23:48:32",
"22/07/2020 00:18:53",
"23/07/2020 00:49:12",
"23/07/2020 01:19:30"
],
"hostname" : "MyHostname1",
"ip" : "142.0.111.79",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "LogonUI.exe",
"date" : "23/07/2020 10:26:04",
}
{
"_id" : ObjectId("5f18fa823406b7000132d098"),
"last_date" : "22/07/2020 23:48:33",
"history_dates" : [
"22/07/2020 23:48:33",
"23/07/2020 00:18:53",
],
"hostname" : "MyHostName2",
"ip" : "142.0.111.54",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "svchost.exe",
"date" : "23/07/2020 10:26:04",
}
I'm needing to make a find to my database (Using Spring Data), to retrieve the same objects, but with the "history_dates"'s array filtered between the 2 dates recieved.
For example, if my 2 recieved dates are: "23/07/2020" and "24/07/2020", I want MongoDB to return the next objects;
{
"_id" : ObjectId("5f18fa823406b7000132d097"),
"last_date" : "22/07/2020 23:48:32",
"history_dates" : [
"23/07/2020 00:49:12",
"23/07/2020 01:19:30"
],
"hostname" : "MyHostname1",
"ip" : "142.0.111.79",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "LogonUI.exe",
"date" : "23/07/2020 10:26:04",
}
{
"_id" : ObjectId("5f18fa823406b7000132d098"),
"last_date" : "22/07/2020 23:48:33",
"history_dates" : [
"23/07/2020 00:18:53"
],
"hostname" : "MyHostName2",
"ip" : "142.0.111.54",
"component" : "C:\\Windows\\System32\\es-ES\\KernelBase.dll.mui",
"process" : "svchost.exe",
"date" : "23/07/2020 10:26:04",
}
I'm really ignorant about MongoDB's queries, and I have been trying to make this with Spring Data all the week.
UPDATE 1.
Thanks varman, and do you know how can i just retrieve the documents with filtered arrays not empty?
答案1
得分: 1
所以基本上你需要进行过滤。MongoTemplate
提供了许多用于 MongoDB 的操作,如果一些方法在 MongoTemplate 中不存在,我们可以使用 Bson Document
模式。在这种情况下,可以参考这篇文章:将Mongo shell查询转换的技巧。
实际上,你需要一个类似下面这样的Mongo查询。可以使用以下其中一种方法,比如 $addFields
。你还可以使用 $project
、$set
等等。在这里,$addFields
会覆盖你的 history_dates
。(它也用于向文档中添加新字段)。
{
$addFields: {
history_dates: {
$filter: {
input: "$history_dates",
cond: {
$and: [
{
$gt: ["$$this", "23/07/2020"]
},
{
$lt: ["$$this", "24/07/2020"]
}
]
}
}
}
}
}
在 Mongo Playground 中查看实际效果。
你需要将这个转换为 Spring Data。所以在你的类中用 @Autowired
注入 MongoTemplate。
@Autowired
MongoTemplate mongoTemplate;
方法如下:
public List<Object> filterDates() {
Aggregation aggregation = Aggregation.newAggregation(
a -> new Document("$addFields",
new Document("history_dates",
new Document("$filter",
new Document("input", "$history_dates")
.append("cond",
new Document("$and",
Arrays.asList(
new Document("$gt", Arrays.asList("$$this", "23/07/2020")),
new Document("$lt", Arrays.asList("$$this", "24/07/2020"))
)
)
)
)
)
)
).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_CLASS.class), Object.class).getMappedResults();
}
MongoTemplate 并不提供 $addFields
和 $filter
的添加方法。所以我们只能使用 bson document 模式。我没有在 Spring 中测试过这个。
英文:
So basically you need to do filter. MongoTemplate
offers a lot of operation for mongodb, if some methods don't exist in MongoTemplate, we can go with Bson Document
pattern. In that case, try this article: Trick to covert mongo shell query.
Actually you need a Mongo query something like following. Using $addFields
one of the methods shown below. But you can use $project
, $set
etc. Here $addFields
overwrites your history_dates
. (It uses to add new fields to document too).
{
$addFields: {
history_dates: {
$filter: {
input: "$history_dates",
cond: {
$and: [{
$gt: ["$$this", "23/07/2020"]
},
{
$lt: ["$$this", "24/07/2020"]
}
]
}
}
}
}
}
Working Mongo playground.
You need to convert this into spring data. So @Autowired
the MongoTemplate in you class.
@Autowired
MongoTemplate mongoTemplate;
The method is,
public List<Object> filterDates(){
Aggregation aggregation = Aggregation.newAggregation(
a->new Document("$addFields",
new Document("history_dates",
new Document("$filter",
new Document("input","$history_dates")
.append("cond",
new Document("$and",
Arrays.asList(
new Document("$gt",Arrays.asList("$$this","23/07/2020")),
new Document("$lt",Arrays.asList("$$this","24/07/2020"))
)
)
)
)
)
)
).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_CLASS.class), Object.class).getMappedResults();
}
Mongo template doesn't provide add methods for $addFields
and $filter
. So we just go with bson document pattern. I haven't tested this in Spring.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论