問題描述
假設(shè)我有一系列格式如下的文檔:
Suppose that I have a series of documents with the following format:
{
"_id": "3_0",
"values": ["1", "2"]
}
我想獲得在單個(gè)字段中連接的數(shù)組值的投影:
and I would like to obtain a projection of the array's values concatenated in a single field:
{
"_id": "3_0",
"values": "1_2"
}
這可能嗎?我試過 $concat
但我想我不能使用 $values
作為 $concat
的數(shù)組.
Is this possible? I have tried $concat
but I guess I can't use $values
as the array for $concat
.
推薦答案
在現(xiàn)代 MongoDB 版本中,您可以.您仍然不能直接"將數(shù)組應(yīng)用到 $concat
,但是您可以使用 $reduce
處理數(shù)組元素并生成:
In Modern MongoDB releases you can. You still cannot "directly" apply an array to $concat
, however you can use $reduce
to work with the array elements and produce this:
db.collection.aggregate([
{ "$addFields": {
"values": {
"$reduce": {
"input": "$values",
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ { "$indexOfArray": [ "$values", "$$this" ] }, 0 ] },
"then": { "$concat": [ "$$value", "$$this" ] },
"else": { "$concat": [ "$$value", "_", "$$this" ] }
}
}
}
}
}}
])
當(dāng)然結(jié)合 $indexOfArray
當(dāng)它是數(shù)組的第一個(gè)"索引時(shí),不與 "_"
下劃線連接".
Combining of course with $indexOfArray
in order to not "concatenate" with the "_"
underscore when it is the "first" index of the array.
我的額外愿望"也得到了$sum
的回答:
Also my additional "wish" has been answered with $sum
:
db.collection.aggregate([
{ "$addFields": {
"total": { "$sum": "$items.value" }
}}
])
<小時(shí)>
一般來說,這種類型的聚合運(yùn)算符會(huì)使用一組項(xiàng)目.這里的區(qū)別在于它表示編碼表示中提供的aguments"數(shù)組",而不是當(dāng)前文檔中存在的數(shù)組元素".
This kind of gets raised a bit in general with aggregation operators that take an array of items. The distinction here is that it means an "array" of "aguments" provided in the coded representation a opposed to an "array element" present in the current document.
真正實(shí)現(xiàn)文檔中存在的數(shù)組中的項(xiàng)目連接的唯一方法是執(zhí)行某種 JavaScript 選項(xiàng),例如 mapReduce:
The only way you can really do the kind of concatenation of items within an array present in the document is to do some kind of JavaScript option, as with this example in mapReduce:
db.collection.mapReduce(
function() {
emit( this._id, { "values": this.values.join("_") } );
},
function() {},
{ "out": { "inline": 1 } }
)
當(dāng)然,如果您實(shí)際上并未聚合任何內(nèi)容,那么最好的方法可能是在您的客戶端代碼中簡單地執(zhí)行加入"操作,以便對查詢結(jié)果進(jìn)行后處理.但是,如果它需要跨文檔用于某種目的,那么 mapReduce 將是您唯一可以使用它的地方.
Of course if you are not actually aggregating anything, then possibly the best approach is to simply do that "join" operation within your client code in post processing your query results. But if it needs to be used in some purpose across documents then mapReduce is going to be the only place you can use it.
我可以添加例如"我希望這樣的東西可以工作:
I could add that "for example" I would love for something like this to work:
{
"items": [
{ "product": "A", "value": 1 },
{ "product": "B", "value": 2 },
{ "product": "C", "value": 3 }
]
}
總的來說:
db.collection.aggregate([
{ "$project": {
"total": { "$add": [
{ "$map": {
"input": "$items",
"as": "i",
"in": "$$i.value"
}}
]}
}}
])
但它不起作用,因?yàn)?$add
需要參數(shù)而不是文檔中的數(shù)組.嘆!:(.對此的設(shè)計(jì)"推理的一部分可以這樣說,僅僅因?yàn)?它是一個(gè)數(shù)組或列表"的奇異值從轉(zhuǎn)換的結(jié)果中傳入,它不是保證"那些是實(shí)際上是運(yùn)算符期望的有效"奇異數(shù)值類型值.至少在當(dāng)前實(shí)現(xiàn)的類型檢查"方法中不是.
But it does not work that way because $add
expects arguments as opposed to an array from the document. Sigh! :(. Part of the "by design" reasoning for this could be argued that "just because" it is an array or "list" of singular values being passed in from the result of the transformation it is not "guaranteed" that those are actually "valid" singular numeric type values that the operator expects. At least not at the current implemented methods of "type checking".
這意味著現(xiàn)在我們?nèi)匀槐仨氝@樣做:
That means for now we still have to do this:
db.collection.aggregate([
{ "$unwind": "$items" },
{ "$group": {
"_id": "$_id",
"total": { "$sum": "$items.value" }
}}
])
遺憾的是,也沒有辦法應(yīng)用這樣的分組運(yùn)算符來連接字符串.
And also sadly there would be no way to apply such a grouping operator to concatenate strings either.
因此,您可以希望對此進(jìn)行某種更改,或者希望進(jìn)行一些更改,以允許在 $map
以某種方式操作.更好的是,新的 $join
操作也會(huì)受到歡迎.但這些在撰寫本文時(shí)不存在,并且可能在未來一段時(shí)間內(nèi)不會(huì)存在.
So you can hope for some sort of change on this, or hope for some change that allows an externally scoped variable to be altered within the scope of a $map
operation in some way. Better yet a new $join
operation would be welcome as well. But these do not exist as of writing, and probably will not for some time to come.
這篇關(guān)于將數(shù)組中的字符串值連接到 MongoDB 的單個(gè)字段中的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!