我想搜索數組中的字段,並且想知道數組中的字段的索引是否可以找到它? 例如:通過相對數組元素位置查找文檔
doc1: {id:123, hobby:['chess','cards','dance']}
doc2: {id:123, hobby:['cards','dance','chess']}
我只想搜索具有 chess
和cards
但只有具有chess
card
前一個文件。所以如果是doc1
。
我想搜索數組中的字段,並且想知道數組中的字段的索引是否可以找到它? 例如:通過相對數組元素位置查找文檔
doc1: {id:123, hobby:['chess','cards','dance']}
doc2: {id:123, hobby:['cards','dance','chess']}
我只想搜索具有 chess
和cards
但只有具有chess
card
前一個文件。所以如果是doc1
。
您可以用$where
運營商做到這一點,與$all
操作偶聯,以保持其合理高性能:
db.test.find({
// Find all the docs where hobby contains both 'cards' and 'chess'
hobby: {$all: ['cards', 'chess']},
// Of those, run this $where query that evaluates the indexes of the matched elements
$where: "this.hobby.indexOf('cards') > this.hobby.indexOf('chess')"
})
上hobby
添加一個索引以獲得最佳性能。
對於你實際上有$match
階段使用.aggregate()
爲「查詢」,以可能的匹配縮小到包含$all
數組中的元素文檔的最佳性能,並$redact
從其餘結果進行過濾:
db.test.aggregate([
{ "$match": { "hobby": { "$all": [ "chess", "cards" ] } } },
{ "$redact": {
"$cond": {
"if": {
"$eq": [
{ "$filter": {
"input": "$hobby",
"as": "hobby",
"cond": {
"$or": [
{ "$eq": [ "$$hobby", "chess" ] },
{ "$eq": [ "$$hobby", "cards" ] }
]
}
}},
["chess","cards"]
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
的作品是因爲$filter
只能返回匹配這裏給出的條件的元素,並將其返回「以相同的順序」它們被存儲在原始文檔中的原因。
一旦「過濾」下,該陣列然後應是完全匹配用於內容["chess","cards"]
如果確實原始數組中的那些元件都以該順序。
請注意,雖然它可能「看起來」更簡單,但您不能使用"set operators"來測試此操作,因爲「sets」實際上並未被認爲是有序的。
所以你需要維護順序的東西,而$filter
真的是唯一能夠以有效的方式對數組內容做到這一點的東西。所以這個解決方案實際上僅限於需要一個MongoDB 3.2或更高版本才能實際工作。
對於較老的版本中,使用$where
對的數組元素作爲附加濾波器使用$all
施加.indexOf()
測試看到answer from JohnnyHK。
但是,如果您的MongoDB 3.2具有可用的運算符,那麼可用於聚合框架的本機編碼操作運行速度比$where
的JavaScript評估要快得多,應優先使用。