如何在mongo选择器中使用过滤器的默认值



我正在尝试将筛选器应用于mongo查找查询。其想法是,如果过滤器有值,mongo选择器将限制返回的内容,但如果没有指定过滤器(过滤器有null或默认值),则不应限制查询。如果指定了过滤器,我知道如何让过滤器工作,但如果没有指定过滤器,我不确定如何确保它返回未过滤的结果。如果过滤器未指定或为默认值,如何让find查询返回集合中的所有文档?

仅供参考:我正在Meteor项目中使用它,并将使过滤器成为会话变量,以使返回的内容动态。

示例集合:

/* 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。

假设每个文档都有两个键,则只能使用return {$ne:null}。如果您想在密钥存在但其值为null的情况下使If工作,您也可以return {$exists:true}

我可以建议您创建一个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);
}

当您实际想要过滤具有非真值(如0或空字符串)的字段时,会有什么意外行为。

最新更新