我有一个具有以下结构的集合:
{
"_id" : ObjectId("59ef54445134d7d70e1cf531"),
"CustomerId" : "Gym_2",
"History" : [
{
"Created_At" : ISODate("2017-10-24T14:54:59Z"),
"Unit" : 600,
"ReferenceCode" : "1cd15b4d-bc42-4a51-a8b3-307db6dc3dee",
},
{
"Created_At" : ISODate("2017-10-28T00:22:19Z"),
"Sent" : true
},
{
"Created_At" : ISODate("2017-10-29T10:22:23Z"),
"Unit" : 600,
"ReferenceCode" : "998e7fce-8a1c-4f7c-b48c-c02cb5c5ad5c",
}
]
}
{
"_id" : ObjectId("59ef54465134d7d70e1cf534"),
"CustomerId" : "Gym_1",
"History" : [
{
"Created_At" : ISODate("2017-10-24T14:55:02Z"),
"Unit" : 600,
"ReferenceCode" : "d19ebeec-bd81-4a0a-aed5-006f746b50ff",
},
{
"Unit" : 600,
"ReferenceCode" : "a991504f-be1f-4e77-b59f-fba73c59e6f1",
"Created_At" : ISODate("2017-10-26T13:51:14Z")
}
]
}
我尝试构建一个只返回CustomerId
的查询以及没有设置"Sent"
字段的历史对象。
结果应如下所示:
{
"_id" : ObjectId("59ef54445134d7d70e1cf531"),
"CustomerId" : "Gym_2",
"History" : [
{
"Created_At" : ISODate("2017-10-24T14:54:59Z"),
"Unit" : 600,
"ReferenceCode" : "1cd15b4d-bc42-4a51-a8b3-307db6dc3dee",
},
{
"Created_At" : ISODate("2017-10-29T10:22:23Z"),
"Unit" : 600,
"ReferenceCode" : "998e7fce-8a1c-4f7c-b48c-c02cb5c5ad5c",
}
]
}
{
"_id" : ObjectId("59ef54465134d7d70e1cf534"),
"CustomerId" : "Gym_1",
"History" : [
{
"Created_At" : ISODate("2017-10-24T14:55:02Z"),
"Unit" : 600,
"ReferenceCode" : "d19ebeec-bd81-4a0a-aed5-006f746b50ff",
},
{
"Unit" : 600,
"ReferenceCode" : "a991504f-be1f-4e77-b59f-fba73c59e6f1",
"Created_At" : ISODate("2017-10-26T13:51:14Z")
}
]
}
我能够达到的最接近的是以下查询:
db.Customers.aggregate([
{$project:{"Sent":{$exists:false},count:{$size:"$History" }}}
]);
但我得"errmsg" : "Unrecognized expression '$exists'"
。
我怎样才能达到这个结果?
答案 0 :(得分:1)
您的问题有一个解决方案,聚合框架绝对是实现您想要的正确方法。要修改嵌套集合,您必须:
投放您的数据以接收原始表格
import java.io.FileWriter
class Main{
static void main(String[] args)
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
println "Enter the number of items:"
int n = Integer.parseInt(br.readLine())
String[] item =new String[n]
Double[] price =new Double[n]
int[] quantity = new int[n]
for(int i=0; i<n;i++)
{
int it = i+1
println "Enter item $it details: "
item[i] = br.readLine()
price[i] = Double.parseDouble(br.readLine()).round(2)
quantity[i] = Integer.parseInt(br.readLine())
}
String COMMA_DELIMITER = ","
String NEW_LINE_SEPARATOR = "\n"
try
{
FileWriter fileWriter = new FileWriter("invoicedetails.csv")
for(int j=0; j<n;j++)
{
fileWriter.append(item[j])
fileWriter.append(COMMA_DELIMITER)
fileWriter.append(price[j])
fileWriter.append(COMMA_DELIMITER)
fileWriter.append(quantity[j])
fileWriter.append(NEW_LINE_SEPARATOR)
}
}
catch(Exception e)
{
println e
}
}
}
正如您所看到的,此查询相当复杂,对于较大的集合,您可能会遇到性能问题,因为我们做的不仅仅是简单的集合过滤。因此,虽然它有效但我建议您应该考虑更改数据模型,例如将每个历史项目作为单独的文档,如下所示:
db.customers.aggregate([
{$unwind: "$History"},
{$match: {"History.Sent": {$exists: false}}},
{$group: {"_id": { "_id": "$_id", "CustomerId": "$CustomerId" }, History: { $push: "$History"} }},
{$project: { "_id": "$_id._id", "CustomerId": "$_id.CustomerId", History: 1}}
]);
然后您的查询将只是简单查找$ exists。