正如在評論前面所述,基本查詢「發現」是用$or
在這裏,這也確實短路匹配,其中返回true
的首要條件只是一個簡單的事情。只有一個數組此元件,從而無需$elemMatch
,只是用「點號」,因爲多場比賽不要求:
db.messages.find({
"$or": [
{ "content": { "$regex": ".*Makefile.*" } },
{ "comments.content": { "$regex": ".*Makefile.*" } }
]
})
這並實際匹配的文件能夠滿足這些條件,這就是.find()
所做的。然而,你似乎在尋找的東西有點「funkier」你想在「父」結果和「子」結果之間「辨別」。
這有點超出了.find()
的範圍,這種操作實際上是MongoDB其他操作的範疇。不幸的是,當您正在查找「字符串的一部分」以匹配您的條件時,在諸如聚合框架之類的東西中不存在與「$regex
」操作相當的「邏輯」操作。如果它是最好的選擇,但是沒有這樣的comparison operator,並且邏輯比較就是你想要的。這同樣適用於基於「文本」的搜索,因爲仍然需要從孩子中辨別父母。
不是最理想的方法,因爲它確實涉及JavaScript處理,但這裏的下一個最佳選項是mapReduce()
。
db.messages.mapReduce(
function() {
// Check parent
if (this.content.match(re) != null)
emit(
{ "_id": this._id, "type": "P", "index": 0 },
{
"posted": this.posted,
"author": this.author,
"content": this.content
}
);
var parent = this._id;
// Check children
this.comments.forEach(function(comment,index) {
if (comment.content.match(re) != null)
emit(
{ "_id": parent, "type": "C", "index": index },
{
"posted": comment.posted,
"author": comment.author,
"content": comment.content
}
);
});
},
function() {}, // no reduce as all are unique
{
"query": {
"$or": [
{ "content": { "$regex": ".*Makefile.*" } },
{ "comments.content": { "$regex": ".*Makefile.*" } }
]
},
"scope": { "re": /.*Makefile.*/ },
"out": { "inline": 1 }
}
)
基本上相同的查詢輸入,因爲這並選擇「文件」你想,真的只用「範圍」這裏是它使得它很容易就能在正則表達式作爲參數傳遞,而不重編寫JavaScript代碼以便每次都包含該值。
這裏的邏輯非常簡單,只需對每個「非規範化」元素進行測試,以查看正則表達式條件是否與該特定元素匹配。結果返回「去歸一化」並辨別匹配的元素是父母還是孩子。
你可以更進一步,不用費心去檢查孩子,如果父母是一個匹配,只需將其移動到else
。以同樣的方式,你甚至可以通過某種方式返回「第一」兒童比賽,如果這是你的願望。
無論如何,這應該設置你的最終代碼看起來像什麼路徑。但是,這是實現在服務器上處理這種區別的唯一方法的基本方法,並且客戶端後處理將遵循大致相同的模式。
能否請您提供的搜索用例的詳細信息?你想在一個查詢中搜索嗎? – 2014-09-02 21:26:10
查找內容中的字符串,包括「父」和「子」註釋。如果可以輕鬆完成,單個查詢將非常棒。 – kviktor 2014-09-02 21:30:39
如果您可以搜索正則表達式,可以使用:{$或:[{'content':{$ regex:'您的搜索正則表達式'}},{'comments':{$ elemMatch:{'content':{ $ regex:'您的搜索正則表達式'}}}]}。這會起作用嗎? – 2014-09-02 21:36:16