2017-07-07 38 views
1

我目前在SaltStack上使用MongoDB作为返回后端,我需要查询数据库,例如获取失败作业的步骤列表,每个jobReturn是一个像这样的对象(这是它的一部分) :如何在子文档的属性上过滤聚合?

{ 
    "_id" : ObjectId("595d12c99fee8e5d23f344a8"), 
    "fun" : "state.apply", 
    "jid" : "20170705162344866073", 
    "return" : { 
     "svn_|-Template tideway should have the revision HEAD active for the staging environment (Live)_|-http://svn-svc-xxx-es/staging/xxx-template-tideway/trunk_|-latest" : { 
      "comment" : "Checked out revision 456.", 
      "name" : "http://svn.svc.xxx.es/staging/xxx-template-tideway/trunk", 
      "start_time" : "18:24:13.939000", 
      "result" : true, 
      "duration" : 752.0, 
      "__run_num__" : 35, 
      "changes" : { 
       "new" : "http://svn.svc.xxx.es/staging/xxx-template-tideway/trunk", 
       "revision" : "456\r" 
      }, 
      "__id__" : "Template tideway should have the revision HEAD active for the staging environment (Live)" 
     }, 
     "win_dacl_|-The application user should have full access to the application directories_|-C:\\inetpub\\wwwroot_|-present" : { 
      "comment" : "", 
      "name" : "C:\\inetpub\\wwwroot", 
      "start_time" : "18:24:39.668000", 
      "result" : true, 
      "duration" : 7.0, 
      "__run_num__" : 61, 
      "changes" : {}, 
      "__id__" : "The application user should have full access to the application directories" 
     }, 
     "svn_|-Template capucine should have the revision HEAD active for the staging environment (Live)_|-http://svn-svc-xxx-es/staging/xxx-template-capucine/trunk_|-latest" : { 
      "comment" : "Checked out revision 456.", 
      "name" : "http://svn.svc.xxx.es/staging/xxx-template-capucine/trunk", 
      "start_time" : "18:24:07.544000", 
      "result" : true, 
      "duration" : 673.0, 
      "__run_num__" : 23, 
      "changes" : { 
       "new" : "http://svn.svc.xxx.es/staging/xxx-template-capucine/trunk", 
       "revision" : "456\r" 
      }, 
      "__id__" : "Template capucine should have the revision HEAD active for the staging environment (Live)" 
     }, 
     ..... 
    } 
} 

这里有个例子,我需要得到这个对象,但与所有的“回报”有“结果”的对象:我试图用$project

,但它只是工作列表。

我无法修改应用程序放置数据的方式。我同意在这个模式中一个对象列表将会是一个更好的解决方案。

这样做的最好方法是什么?

+1

看看这有助于https://stackoverflow.com/questions/44882150/collect-distinct-field-names-at -spec-level-with-specific-condition/44883850#44883850 – Veeram

回答

1

我发现使用MongoDB中的$objectToArray表达3.4.4+的解决方案:

db.saltReturns.aggregate([ 
    { $match: { "fun": { $eq: "state.apply" }}}, 
    { $project: { 
     matches: { 
      $filter: { 
       input: { $objectToArray: "$return" }, 
       as: "return", 
       cond: { $eq: ["$$return.v.result", true] } 
      } 
     } 
    }} 
]) 
+1

你真的应该学会在这里使用'$ objectToArray'作为''filter''的''input'''选项的参数,而不是使用单独的' $ project'阶段。原因是“实际发生”是“$ project”运行“所有数据”以便进行更改。所以你基本上都跑遍了所有结果两次。另一个教训是,我们现在正在“强迫一个数组”,实际上对它做一些建设性的建议。这是一个指标,您的数据首先应该像这样构建。这提供了一个高性能的查询。 –