用AND运算符searchmongoosesearch文本

所以我想要做的是与mongoose进行“AND”search到mongoDb,但结果来自“OR”search。 有这样的设置吗? 这是查询的样子:

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); }); 

让我们asume searchParams =餐厅伦敦;

这将在文档中产生“餐厅”或“伦敦”的结果。 我希望它能够在“餐厅”和“伦敦”这两个文件中产生结果。

在search词语周围加上引号可将默认行为更改为AND。

https://docs.mongodb.org/manual/reference/operator/query/text/#phrases

 exampleModel.find({ $text: { $search: "\"restaurant\" \"london\"" } }, { score: { $meta: "textScore" } }, { lean: true }).select(exampleViewModel).limit(1000).sort({ score: { $meta: 'textScore' } }).exec(function (err, results) { next(null, results); }); 

正如Carlos提到的,一个可以接受的解决方法是在单词search条件下放置双引号,以使其成为强制性的:

 apple banana => "apple" "banana" 

这会产生类似于Elasticsearch等高级search引擎的AND运算符的行为。

但是,如果您打算通过前面的连字符( -exclude )或精确短语( "several words wrapped in double quotes" )来支持单词排除,那么在dynamic的用户生成的查询上实现这一点可能会变得杂乱无章,这两者都是有效的句法由$text支持。

所以,这是我写的一个函数,如果它没有用连字符开头,或者包含在一个精确的短语中,用双引号将查询中的每个单词包装起来。

input:

 apple banana "huge orange trees" -pineapple "lemon" 

输出:

 "apple" "banana" "huge orange trees" -pineapple "lemon" 

在每个双引号之前,务必使用前面的反斜杠来避开此函数的输出。 然后,将它作为MongoDB find()查询的$searchparameter passing。

 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; }