2016-06-09 68 views
5

它基本上是標題所說的。查找其數組字段包含給定數組中至少n個元素的文檔

輸入:myArray =詞語

的陣列我有具有字段 wordsCollection一個模型,該模型是一個數組字段。

我如何才能找到其wordsCollectionsmyArray

+0

顯示數據庫結構,什麼到目前爲止喲試圖使其工作。 – Shrabanee

+0

我不認爲這個問題很清楚,我不需要提供數據庫結構。我不確定mongodb是否提供這樣的API調用,所以我只是在考慮迭代所有文檔....當然,這聽起來很糟糕 –

+0

「myArray」和「wordsCollection」的項是唯一的嗎? – Redu

回答

3

讓我們說,我們有我們的集合中的下列文件:

{ "_id" : ObjectId("5759658e654456bf4a014d01"), "a" : [ 1, 3, 9, 2, 9, 0 ] } 
{ "_id" : ObjectId("5759658e654456bf4a014d02"), "a" : [ 0, 8, 1 ] } 
{ "_id" : ObjectId("5759658e654456bf4a014d03"), "a" : [ 0, 8, 432, 9, 34, -3 ] } 
{ "_id" : ObjectId("5759658e654456bf4a014d04"), "a" : [ 0, 0, 4, 3, 2, 7 ] } 

和下面的輸入陣列和n = 2

var inputArray = [1, 3, 0]; 

我們可以返回那些數組字段至少包含n個元素的文檔給定的數組使用聚合框架。

$match只選擇那些數組長度大於或等於n的文檔。這可以減少流水線中要處理的數據量。

$redact管道運營商使用使用$cond操作員和特種作戰$$KEEP「保持」的文件,其中的邏輯條件爲真或$$PRUNE邏輯條件處理,其中條件爲假「拋棄」的文件。

在我們的情況下,條件是$gte如果兩個陣列,其中我們計算使用$setIntersection操作者的交叉點的$size是大於或等於2返回true。

db.collection.aggregate(
    [ 
     { "$match": { "a.1": { "$exists": true } } }, 
     { "$redact": { 
      "$cond": [ 
       { "$gte": [ 
        { "$size": { "$setIntersection": [ "$a", inputArray ] } }, 
        2 
       ]}, 
       "$$KEEP", 
       "$$PRUNE" 
      ] 
     }} 
    ] 
) 

主要生產:

{ "_id" : ObjectId("5759658e654456bf4a014d01"), "a" : [ 1, 3, 9, 2, 9, 0 ] } 
{ "_id" : ObjectId("5759658e654456bf4a014d02"), "a" : [ 0, 8, 1 ] } 
{ "_id" : ObjectId("5759658e654456bf4a014d04"), "a" : [ 0, 0, 4, 3, 2, 7 ] } 
+0

您的解決方案非常棒。我從中學到很多mongodb。 Thks :) –

0

使用聚合的至少n個元素是模型的所有文件。

$match聚合管道,您可以使用$size和​​

+0

我會試試,如果它的工作,以避免不斷更新「數」字段可能是非常有用的!不知道爲什麼你被低估了,我upvote回 –

+0

@libik:我會試一試 –

+0

你不能在'$ match'中使用'$ size'這裏。我沒有看到這是怎麼解決這個問題的。順便說一句@JulienLeray,你不贊成一個答案,因爲它已被低估。根據內容的質量投票。 – styvane

0

你並不需要在這裏沒有任何框架是非常簡單的用JS。我不得不創建一個測試用例,請原諒人羣。我們發明了一種新的Array方法。 Array.prototype.intersect()。它會給我們兩個數組的共同項目。所以如果我們有兩個文本段落,我們可以將每個單詞中的一個(不重複)插入兩個數組中,然後將它們交叉。讓我們來看看...

Array.prototype.intersect = function(a) { 
 
    return this.filter(e => a.includes(e)); 
 
}; 
 
var text = "Last week we installed a kitty door so that our cat could come and go as she pleases. Unfortunately, we ran into a problem. Our cat was afraid to use the kitty door. We tried pushing her through, and that caused her to be even more afraid. The kitty door was dark, and she couldn’t see what was on the other side. The first step we took in solving this problem was taping the kitty door open. After a couple of days, she was confidently coming and going through the open door. However, when we removed the tape and closed the door, once again, she would not go through. They say you catch more bees with honey, so we decided to use food as bait. We would sit next to the kitty door with a can of wet food and click the top of the can. When kitty came through the closed door, we would open the can and feed her. It took five days of doing this to make her unafraid of using the kitty door. Now we have just one last problem; our kitty controls our lives!", 
 
    given = "People often install a kitty door, only to discover that they have a problem. The problem is their cat will not use the kitty door. There are several common reasons why cats won’t use kitty doors. First, they may not understand how a kitty door works. They may not understand that it is a little doorway just for them. Second, many kitty doors are dark and cats cannot see to the other side. As such, they can’t be sure of what is on the other side of the door, so they won’t take the risk. One last reason cats won’t use kitty doors is because some cats don’t like the feeling of pushing through and then having the door drag across their back. But don’t worry—there are solutions to this problem.\nThe first step in solving the problem is to prop the door open with tape. This means your cat will now be able to see through to the other side; your cat will likely begin using the kitty door immediately. Once your cat has gotten used to using the kitty door, remove the tape. Sometimes cats will continue to use the kitty door without any more prompting. If this does not happen, you will want to use food to bribe your cat. When it’s feeding time, sit on the opposite side of the door from your cat and either click the top of the can or crinkle the cat food bag. Open the door to show your cat that it is both you and the food waiting on the other side of the door. Repeat this a couple times, and then feed your cat. After a couple days of this, your kitty door problem will be gone.", 
 
// get one of each word of "text" lowercased and insert into textar 
 
    textar = Array.from(new Set(text.match(/\b\w+\b/g).map(e => e.toLowerCase()))), 
 
// get one of each word of "given" lowercased and insert into textar 
 
givenar = Array.from(new Set(given.match(/\b\w+\b/g).map(e => e.toLowerCase()))), 
 
    shared = givenar.intersect(textar); 
 
console.log(JSON.stringify(shared)); 
 
console.log(shared.length) // this is your result to decide upon.

+0

你爲什麼要那樣做?不,認真。 – styvane

+0

sr,但也許你誤解了我的問題,這是關於查詢貓鼬 –

相關問題