2015-12-17 21 views
1

我想將過濾器應用到mongo查找查詢。這個想法是,如果一個過濾器有值,mongo選擇器將限制返回的內容,但是如果沒有指定過濾器(過濾器有一個空或默認值),它不應該限制查詢。我知道如何讓過濾器工作,如果指定了過濾器,但我不確定如何確保在未指定過濾器的情況下返回未過濾。如果篩選器未指定或處於其默認值,如何才能使查找查詢返回集合中的所有文檔?如何在mongo選擇器中使用過濾器的默認值?

僅供參考:我在Meteor項目中使用它,並將使過濾器成爲Session變量,以使返回的動態變量生效。

例寶典:

/* example documents in SampleCollection 

{ name: "sample1", fieldA: "foo", fieldB: "foo" } 
{ name: "sample2", fieldA: "foo", fieldB: "bar" } 
{ name: "sample3", fieldA: "bar", fieldB: "foo" } 
{ name: "sample4", fieldA: "bar", fieldB: "bar" } 

*/ 

例JS代碼:

var filters = { 
    fieldA: null, 
    fieldB: null 
}; 

var getFieldASelector = function() { 
    if (filters.fieldA) { 
     return { $eq: fieldA }; 
    } else { 
     /* fieldA has a falsey value which is the default 
      and therefore should not limit the find query */ 
     // not sure what to return here 
     return {}; 
    }; 
}; 

var getFieldBSelector = function() { 
    if (filters.fieldB) { 
     return { $eq: fieldB }; 
    } else { 
     /* fieldB has a falsey value which is the default 
      and therefore should not limit the find query */ 
     // not sure what to return here 
     return {}; 
    }; 
}; 

var results = SampleCollection.find({ 
    fieldA: getFieldASelector(), 
    fieldB: getFieldBSelector() 
}); 

在這個例子中results應該歸還所有四個文件。如果filter = { fieldA: "foo", fieldB: null };results應該返回文檔sample1和sample2。

回答

1

假設每個文檔都有兩個鍵,那麼您可以只使用return {$ne:null}。如果你想讓工作如果工作,如果鑰匙存在,但它的值爲空,你也可以return {$exists:true}

0

我可以建議你創建一個selector對象並根據給定的過濾器填充它。雖然我不確定這是否是你要求的。

function getResults(filter){ 
    var selector = {}; 

    // what this does is filters aways keys with non-truthy values 
    Object.keys(filter).reduce(function (prev, curr){ 
     var val = filter[curr]; 
     if (!!val) 
      prev[curr] = filter[curr]; 
     return prev; 
    }, selector); 

    return SampleCollection.find(selector); 
} 

出什麼意外的行爲,當你真正要過濾的字段與非truthy值,如0或空字符串。

+0

這可能工作,我會用流星的會話變量來測試它,看看它是否工作時動態更改過濾器對象。我正在尋找的是在SampleCollection.find({fieldA:{}})中提供比較(例如:{$ eq:「foo」}),它返回所有文檔,而不管字段A是什麼。如果filter.fieldA是真的,它會實際限制查詢。那有意義嗎? – DavidC

+0

我想你可以改變'prev [curr] = filter [curr];'到'prev [curr] = {$ eq:filter [curr]};'' – jkris

相關問題