2014-03-31 36 views
1

我有一个包含两个不同(但相似)结构的文档的集合,其中一些字段具有单个字符串值的字段“someField”,另一些字段具有字段“someField” -fields。查询具有不同子字段异构的文档

我可以查询以下两种类型的文档,当字符串为字符串时,将someField作为字符串,并且如果子字段为,某些子字段? (很容易获得子字段的字符串或全部

如果您可以格式化子字段以使其看起来像单个字符串文档,则可以获得奖励分数。

包含两种类型的文件(简化的例子)

{ 
    "_id" : ObjectId("53345585cdf2fb6a03f4a7bc"), 
    "document" : { 
     "someField" : "Foo 1, Bar 2", 
    } 
} 
{ 
    "_id" : ObjectId("533455sdfghjfb6a03f4a7bc"), 
    "document" : { 
     "someField" : { 
      "foo": "1", 
      "bar": "2", 
      "wibble": "I don't want this field" 
     } 
    } 
} 

额外的信息采集:

最好我到目前为止是在另一个脚本之后使用两个查询,并加入结果放在一起或代码:

db.someCollection.find(
    { 
     "document.someField.foo":{$exists:false}, 
    }, 
    { 
     "document.someField": 1, 
     _id: 0 
    } 
).forEach(printjson) 

db.someCollection.find(
    { 
     "document.someField.foo":{$exists:true}, 
    }, 
    { 
     "document.someField.foo": 1, 
     "document.someField.bar": 1, 
     _id: 0 
    } 
).forEach(printjson) 

回答

1

你的问题有点抽象,但你可以使用.aggregate()和工作,这种解决方案运营商:

db.collection.aggregate([ 
    { "$project": { 
     "onefield": { "$cond": [ 
      "$document.someField.foo", 
      { 
       "foo": "$document.someField.foo", 
       "bar": "$document.someField.bar" 
      }, 
      "$document.someField" 
     ]} 
    }} 
]) 

这也使得利用三元$cond运营商,以“评估”结果怎么都去看看。

那么,你的项目做子文档场,那么你可以在“重新塑造”给你想要的字段。当他们不要那么你可以转储字段,如(如果你的逻辑需要它)嵌套进一步$cond操作,以确定如何处理该字段。

当然,如果你真的想要的一切作为一个字符串,然后使用$concat要做到这一点,而不是:

db.collection.aggregate([ 
    { "$project": { 
     "onefield": { "$cond": [ 
      "$document.someField.foo", 
      { "$concat": [ 
       "Foo ", 
       "$document.someField.foo", 
       " ,Bar ", 
       "$document.someField.bar" 
      ]}, 
      "$document.someField" 
     ]} 
    }} 
]) 
0

我想@Neil-Lunn's answer可能是更好的(我还在努力将其转化为我的现实世界的例子),但我设法使用JS函数自己做。 *从我的真实世界简化,所以可能包含拼写错误。

db.someCollection.find() 
    .forEach(function(o) { 
     if(o.document.someField.foo) { 
      print("Foo " 
       + o.document.someField.foo 
       + ", Bar " 
       + o.document.someField.bar 
      ); 
     } else { 
      print(o.document.someField); 
     } 
    } 
) 

foo是否存在的条件检查(未定义为假),然后执行必要一些手动字符串连接时。

+0

你总是可以问你另一个问题“真实世界”的例子。如果你正在使用的数据很大,那么你会想不做迭代来完成这个转换。我一定错过了你想要**的字符串,所以我也更新了这个部分。 –

相关问题