我发现了 Mongodb 及其使用管道的查询,我正在为一个案例而苦苦挣扎。
我正在寻找每个 pathsList 文档,我可以在其中找到从位置 B 到位置 C 的路径
假设我有 2 个来自 pathsListsCollection 的 pathsList 文档,它们有一组 path 文档
-------------
pathsList = {
_id: ObjectId(...),
pathIds: [path1Id, path2Id, path3Id]
}
-------------
path1 = {
_id: ObjectId(...),
positionStart: 8,
positionFinal: 10,
index:0
}
-------------
path2 = {
_id: ObjectId(...),
positionStart: 10,
positionFinal: 12,
index:1
}
-------------
path3 = {
_id: ObjectId(...),
positionStart: 12,
positionFinal: 14,
index:2
}
-------------
-------------
pathsList = {
_id: ObjectId(...),
pathIds: [path4Id, path5Id, path6Id]
}
-------------
path4 = {
_id: ObjectId(...),
positionStart: 14,
positionFinal: 12,
index:0
}
-------------
path5 = {
_id: ObjectId(...),
positionStart: 12,
positionFinal: 10,
index:1
}
-------------
path6 = {
_id: ObjectId(...),
positionStart: 10,
positionFinal: 8,
index:2
}
-------------
到目前为止,我已经做了这样的事情:
pathsListCollection.aggregate([
{
$lookup:{
from: "pathsCollection",
localField: "pathIds",
foreignField: "_id",
as: paths
}
},
{
$match:{
paths.positionStart : 10 // first input value
}
},
{
$match:{
paths.positionFinal : 12 // second input value
}
},
])
这样做我得到了 2 个 pathsList 文档。
现在,我如何更改此聚合以仅找到具有特定顺序的 positionStart = 10 和 positionFinal = 12 的聚合 如何仅在第一个表达式已经验证时才尝试验证第二个表达式?
我研究了 $slice,试图在第一个 $match 之后对路径数组进行切片,并继续查询其余部分,但找不到任何相关的语法来执行此操作。
即:使用第一个 pathsList,我用 paths array 到达第一个 $match :
[{
_id: ObjectId(...),
positionStart: 8,
positionFinal: 10,
index:0
},
{
_id: ObjectId(...),
positionStart: 10, // first $match here
positionFinal: 12,
index:1
},
{
_id: ObjectId(...),
positionStart: 12,
positionFinal: 14,
index:2
}]
我想在这样的数组上进行下一个 $match :
[{
_id: ObjectId(...),
positionStart: 10,
positionFinal: 12, // second $match has to start from this elem of the array
index:1
},
{
_id: ObjectId(...),
positionStart: 12,
positionFinal: 14,
index:2
}]
这有可能吗? 首先查询 pathsCollection 而不是 pathsListsCollection 会更容易吗?
但是,我愿意接受任何可以帮助我解决该问题的不同方法或想法 提前致谢
最佳答案
如果我得到这个,那么你想根据给定的匹配 positionStart 和 positionFinish 在这里“切片”。
如果您确实在 "pathsCollection" 上开始查询,实际上性能会更好,因为这是您实际要匹配项目的地方。所以 $match应该“首先”完成并使用 $or在范围内“切片”的表达式:
然后用 $lookup然后,您将只返回 "pathsListCollection" 项,使用“切片”数组格式化:
在您的数据的最小样本上,从“开始”10 到“完成”12 将是:
db.getCollection('pathsCollection').aggregate([
{ "$match": {
"positionStart": { "$gte": 10, "$lte": 12 },
"positionFinal": { "$gte": 10, "$lte": 12 }
}},
{ "$lookup": {
"from": "pathsListCollection",
"localField": "_id",
"foreignField": "pathIds",
"as": "pathsList"
}},
{ "$unwind": "$pathsList" },
{ "$addFields": {
"pathsList.pathIds": {
"$filter": {
"input": "$pathsList.pathIds",
"as": "p",
"cond": { "$eq": [ "$_id", "$$p" ] }
}
}
}},
{ "$unwind": "$pathsList.pathIds" },
{ "$group": {
"_id": "$pathsList._id",
"pathIds": {
"$push": {
"_id": "$_id",
"positionStart": "$positionStart",
"positionFinal": "$positionFinal",
"index": "$index"
}
}
}},
{ "$redact": {
"$cond": {
"if": {
"$and": [
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionStart",
0
]},
10
]},
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionFinal",
-1
]},
12
]}
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
会产生:
/* 1 */
{
"_id" : ObjectId("595db5d8f5f11516540d1185"),
"pathIds" : [
{
"_id" : ObjectId("595db4c7f5f11516540d1183"),
"positionStart" : 10.0,
"positionFinal" : 12.0,
"index" : 1.0
}
]
}
并且将“范围”缩小到“开始”10 和“完成”14,这将是:
db.getCollection('pathsCollection').aggregate([
{ "$match": {
"positionStart": { "$gte": 10, "$lte": 14 },
"positionFinal": { "$gte": 10, "$lte": 14 }
}},
{ "$lookup": {
"from": "pathsListCollection",
"localField": "_id",
"foreignField": "pathIds",
"as": "pathsList"
}},
{ "$unwind": "$pathsList" },
{ "$addFields": {
"pathsList.pathIds": {
"$filter": {
"input": "$pathsList.pathIds",
"as": "p",
"cond": { "$eq": [ "$_id", "$$p" ] }
}
}
}},
{ "$unwind": "$pathsList.pathIds" },
{ "$group": {
"_id": "$pathsList._id",
"pathIds": {
"$push": {
"_id": "$_id",
"positionStart": "$positionStart",
"positionFinal": "$positionFinal",
"index": "$index"
}
}
}},
{ "$redact": {
"$cond": {
"if": {
"$and": [
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionStart",
0
]},
10
]},
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionFinal",
-1
]},
14
]}
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
制作:
/* 1 */
{
"_id" : ObjectId("595db5d8f5f11516540d1185"),
"pathIds" : [
{
"_id" : ObjectId("595db4c7f5f11516540d1183"),
"positionStart" : 10.0,
"positionFinal" : 12.0,
"index" : 1.0
},
{
"_id" : ObjectId("595db4c7f5f11516540d1184"),
"positionStart" : 12.0,
"positionFinal" : 14.0,
"index" : 2.0
}
]
}
它的语法可能看起来有点短,但它可能不是性能最好的选项,因为您不能在相反的情况下“查询”“pathsCollection”,直到 $lookup。实际执行:
db.pathsListCollection.aggregate([
{ "$lookup": {
"from": "pathsCollection",
"localField": "pathIds",
"foreignField": "_id",
"as": "pathIds"
}},
{ "$unwind": "$pathIds" },
{ "$match": {
"pathIds.positionStart": { "$gte": 10, "$lte": 14 },
"pathIds.positionFinal": { "$gte": 10, "$lte": 14 }
}},
{ "$group": {
"_id": "$_id",
"pathIds": { "$push": "$pathIds" }
}},
{ "$redact": {
"$cond": {
"if": {
"$and": [
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionStart",
0
]},
10
]},
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionFinal",
-1
]},
14
]}
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
这是关于 MongoDB 如何实际发布 $lookup 的“反向案例”的最佳形式。当应用于服务器时,可以在“解释”输出中看到:
{
"$lookup" : {
"from" : "pathsCollection",
"as" : "pathIds",
"localField" : "pathIds",
"foreignField" : "_id",
"unwinding" : {
"preserveNullAndEmptyArrays" : false
},
"matching" : {
"$and" : [
{
"positionStart" : {
"$gte" : 10.0
}
},
{
"positionStart" : {
"$lte" : 14.0
}
},
{
"positionFinal" : {
"$gte" : 10.0
}
},
{
"positionFinal" : {
"$lte" : 14.0
}
}
]
}
}
},
{
"$group" : {
在那里显示 $unwind和 $match已经“神奇地”消失了。他们现在当然已经“卷起”到 $lookup 中了。这样当查询相关数据时,你实际上只会那些符合给定条件的结果。
“非最佳”方法是 $filter反而。但实际上来自相关集合的 ALL 结果被返回,然后只有在“完整”数组已经存在时才被删除:
db.pathsListCollection.aggregate([
{ "$lookup": {
"from": "pathsCollection",
"localField": "pathIds",
"foreignField": "_id",
"as": "pathIds"
}},
{ "$addFields": {
"pathIds": {
"$filter": {
"input": "$pathIds",
"as": "p",
"cond": {
"$and": [
{ "$gte": [ "$$p.positionStart", 10 ] },
{ "$lte": [ "$$p.positionStart", 14 ] },
{ "$gte": [ "$$p.positionFinal", 10 ] },
{ "$lte": [ "$$p.positionFinal", 14 ] },
]
}
}
}
}},
{ "$match": {
"pathIds": {
"$elemMatch": {
"positionStart": { "$gte": 10, "$lte": 14 },
"positionFinal": { "$gte": 10, "$lte": 14 }
}
}
}},
{ "$redact": {
"$cond": {
"if": {
"$and": [
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionStart",
0
]},
10
]},
{ "$eq": [
{ "$arrayElemAt": [
"$pathIds.positionFinal",
-1
]},
14
]}
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
还注意到您仍然需要 $match或 $redact鉴于在这种情况下生成的数组条目仍然满足条件,并且由于 $filter 的结果,数组实际上不是“空”的.
路径集合
/* 1 */
{
"_id" : ObjectId("595db4c7f5f11516540d1182"),
"positionStart" : 8.0,
"positionFinal" : 10.0,
"index" : 0.0
}
/* 2 */
{
"_id" : ObjectId("595db4c7f5f11516540d1183"),
"positionStart" : 10.0,
"positionFinal" : 12.0,
"index" : 1.0
}
/* 3 */
{
"_id" : ObjectId("595db4c7f5f11516540d1184"),
"positionStart" : 12.0,
"positionFinal" : 14.0,
"index" : 2.0
}
/* 4 */
{
"_id" : ObjectId("595db616f5f11516540d1186"),
"positionStart" : 14.0,
"positionFinal" : 12.0,
"index" : 0.0
}
/* 5 */
{
"_id" : ObjectId("595db616f5f11516540d1187"),
"positionStart" : 12.0,
"positionFinal" : 10.0,
"index" : 1.0
}
/* 6 */
{
"_id" : ObjectId("595db616f5f11516540d1188"),
"positionStart" : 10.0,
"positionFinal" : 8.0,
"index" : 2.0
}
路径列表集合
/* 1 */
{
"_id" : ObjectId("595db5d8f5f11516540d1185"),
"pathIds" : [
ObjectId("595db4c7f5f11516540d1182"),
ObjectId("595db4c7f5f11516540d1183"),
ObjectId("595db4c7f5f11516540d1184")
]
}
/* 2 */
{
"_id" : ObjectId("595db62df5f11516540d1189"),
"pathIds" : [
ObjectId("595db616f5f11516540d1186"),
ObjectId("595db616f5f11516540d1187"),
ObjectId("595db616f5f11516540d1188")
]
}
关于mongodb - 使用 $lookup 根据匹配条件对数组进行切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44917069/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h