Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用AND运算符进行Mongoose文本搜索_Javascript_Node.js_Mongodb_Mongoose - Fatal编程技术网

Javascript 使用AND运算符进行Mongoose文本搜索

Javascript 使用AND运算符进行Mongoose文本搜索,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,所以我想做的是用mongoose对mongoDb进行“和”搜索,但结果是“或”搜索。有这样的设置吗?这是查询的外观: exampleModel.find({ $text: { $search: searchParams } }, { score: { $meta: "textScore" } }, { lean: true }).select(exampleViewModel).limit(1000).sort({ scor

所以我想做的是用mongoose对mongoDb进行“和”搜索,但结果是“或”搜索。有这样的设置吗?这是查询的外观:

exampleModel.find({
    $text: {
        $search: searchParams
    }
}, {
    score: {
        $meta: "textScore"
    }
}, { lean: true }).select(exampleViewModel).limit(1000).sort({
    score: {
        $meta: 'textScore'
    }
}).exec(function (err, results) {
   next(null, results); 
});
让我们来看看searchParams=伦敦餐厅


这将在带有“餐厅”或“伦敦”字样的文档中产生结果我希望它能在带有“餐厅”和“伦敦”字样的文档中生成结果。

在搜索词周围加上引号,将默认行为更改为AND


正如Carlos所提到的,一种可接受的解决方法是在单词搜索词周围加双引号,使其成为必填项:

apple banana       =>      "apple" "banana"
这会产生类似于Elasticsearch等高级搜索引擎的
操作员的行为

但是,如果您打算通过前面的连字符(
-exclude
)或确切的短语(
“几个单词用双引号括起来”
)来支持单词排除,则在动态用户生成的查询上实现此功能可能会变得混乱,这两种语法都是
$text
支持的有效语法

因此,我编写了一个函数,如果查询中的每个单词前面没有连字符,或者没有包含在一个确切的短语中,那么它会用双引号将每个单词包装起来

输入:

apple banana "huge orange trees" -pineapple "lemon"
"apple" "banana" "huge orange trees" -pineapple "lemon"
输出:

apple banana "huge orange trees" -pineapple "lemon"
"apple" "banana" "huge orange trees" -pineapple "lemon"
确保在每个双引号之前使用前面的反斜杠转义此函数的输出。然后,将其作为MongoDB
find()
查询的
$search
参数传递

function wrapSingleTermsWithDoubleQuotes(query) {
    // Output variable
    var output = "";

    // Keep track of whether to ignore the current word due to the negation operator (-minus)
    var ignoreCurrentWord = false;

    // Keep track of whether we're inside a custom phrase in the query ("exact match")
    var withinCustomPhrase = false;

    // Keep track of whether we need to close a double quote that we opened for the current word
    var openedDoubleQuote = false;

    // Remove all double spacing from the query (we may need a few iterations for this to work)
    while (query.indexOf('  ') != -1) {
        // Replace all occurrences of double spacing with single spacing
        query = query.replace(/  /g, ' ');
    }

    // Trim leading and trailing spaces from the query to normalize the input
    query = query.trim();

    // Start traversing query characters
    for (var i = 0; i < query.length; i++) {
        // Comfort variable
        var char = query[i];

        // Not yet wrapping a term with double quotes?
        if (!openedDoubleQuote) {
            // Not ignoring the current word already (due to an operator) and not within a custom phrase?
            if (!ignoreCurrentWord && !withinCustomPhrase) {
                // Char is not a quote or negation operator?
                if (char != '"' && char != '-') {
                    // This is most likely a single term, let's insert an opening double quote
                    output += '"';

                    // Mark this as true so we remember to close the double-quote when the word's done
                    openedDoubleQuote = true;
                }
                else {
                    // Char is a quote
                    if (char == '"') {
                        // Avoid adding quotes until we encounter the phrase's closing quote
                        withinCustomPhrase = !withinCustomPhrase;
                    }
                    // Char is a negation operator
                    else if (char == '-') {                    
                        // Ignore the current word (don't try to wrap it with double quotes)
                        ignoreCurrentWord = true;
                    }
                }
            }
            else {
                // Ignoring the current word or phrase -- check if we reached the end of the current word (space)
                if (char == ' ') {
                    // In case this was a negative word, it's over now
                    ignoreCurrentWord = false;

                    // Were we inside a custom phrase, the current char is a space, and the previous char was a double quote?
                    if (withinCustomPhrase && i > 0 && query[i - 1] == '"') {
                        // No longer inside a the custom phrase (since we encountered a closing double-quote)
                        withinCustomPhrase = false;
                    }
                }
            }
        }
        else {
            // Within a single term currently -- is current char a space, indicating the end of the single term?
            if (char == ' ') {
                // Add a closing double quote to finish wrapping the single term
                output += '"';

                // We closed our own double-quote
                openedDoubleQuote = false;
            }
        }

        // Add current char to output (we never omit any query chars, only append double-quotes where necessary)
        output += char;
    }

    // Reached the end of the string but still got a quote to close?
    if (openedDoubleQuote) {
        // Add the final double quote
        output += '"';
    }

    // Return algorithm output
    return output;
}
函数wrapSingleTermsWithDoubleQuotes(查询){
//输出变量
var输出=”;
//跟踪是否由于否定运算符(-减号)而忽略当前单词
var ignoreCurrentWord=false;
//跟踪我们是否在查询中的自定义短语中(“精确匹配”)
var with incustomphrase=false;
//跟踪是否需要关闭为当前单词打开的双引号
var openedDoubleQuote=false;
//从查询中删除所有双倍间距(我们可能需要几次迭代才能工作)
while(query.indexOf(“”)!=-1){
//将所有出现的双间距替换为单间距
query=query.replace(//g',);
}
//修剪查询中的前导空格和尾随空格以规范化输入
query=query.trim();
//开始遍历查询字符
for(var i=0;i0&&query[i-1]==='''”){
//不再位于自定义短语的内部(因为我们遇到了结束双引号)
withinCustomPhrase=false;
}
}
}
}
否则{
//在当前单个术语内——当前字符是一个空格,表示单个术语的结束吗?
如果(字符=“”){
//添加结束双引号以完成对单个术语的包装
输出+=“”;
//我们结束了自己的双重报价
openedDoubleQuote=false;
}
}
//将当前字符添加到输出(我们从不忽略任何查询字符,只在必要时附加双引号)
输出+=字符;
}
//已到达字符串末尾,但仍有一个引号要关闭?
如果(openedDoubleQuote){
//添加最后的双引号
输出+=“”;
}
//返回算法输出
返回输出;
}

谢谢。我希望有一个选项,而不必操纵Searchparams字符串。