MongoDB 在多个字段中搜索单词,并且仅返回包含两个单词的结果(文本区域设置“加泰罗尼亚语”)

问题描述 投票:0回答:1

我正在使用 vue 和 mongoose,我需要为“加泰罗尼亚语”中的搜索引擎制定满足以下规范的逻辑:

该集合包含具有以下字段的记录:

  • 问题
  • 回答
  • 替代答案
  • 评论

1.- 如果搜索两个单词,则仅必须出现在包含该单词或必填单词的一个或多个字段中出现的结果。也就是说,如果仅出现其中一个单词或未出现全部,则不会返回该结果。

2.- 例如,如果您在引号之间搜索“Eufór”,我需要结果与所写的完全相同,但如果不带引号,结果可能是包含这些字母的单词,并且会区分重音、大写和元音变音。

有人可以告诉我该怎么做吗?

非常感谢

我期望的搜索结果如下:

1.- 例如:

搜索:瓜迪奥拉·梅西

结果:

{Question: 'Lorem ipsum dolor sit amet **Guardiola** consectetur adipiscing elit **Messi**', Answer: '...', Alternative_answer: '...', Comment: '...'}

{Question: 'Lorem ipsum dolor sit amet **Guardiola** consectetur', Answer: ' sed do eiusmod tempor incididun **Messi** dolore magna aliqua', Alternative_answer: '...', Comment: '...'}


{Question: '...', Answer: ' sed do eiusmod tempor incididun **Guardiola** dolore magna aliqua', Alternative_answer: 'Sed ut perspiciatis unde omnis **Messi** iste natus error sit voluptatem', Comment: '...'}

我尝试使用“$search”功能来完成此操作,但这些文本是加泰罗尼亚语,结果不是我所期望的。

2.- 例如:

搜索:“Eufór”

结果:


{Question: 'Lorem ipsum dolor sit amet **Eufór** consectetur adipiscing elit', Answer: '...', Alternative_answer: '...', Comment: '...'}

{Question: '...', Answer: '...', Alternative_answer: 'Lorem ipsum dolor sit amet **Eufór** consectetur adipiscing elit', Comment: '...'}

搜索:Eufór

结果:


{Question: 'Lorem ipsum dolor sit amet **euforia** consectetur adipiscing elit', Answer: '...', Alternative_answer: '...', Comment: '...'}

{Question: '...', Answer: '...', Alternative_answer: 'Lorem ipsum dolor sit amet **Eufór** consectetur adipiscing elit', Comment: '...'}

{Question: '...', Answer: '...', Alternative_answer: '...', Comment: 'Lorem ipsum dolor sit amet **EUFORÍS** consectetur adipiscing elit'}

写多个字也一样:

搜索:Eufór mal

结果:


{Question: 'Lorem ipsum dolor sit amet **euforia** consectetur adipiscing elit', Answer: '...', Alternative_answer: 'odit aut fugit, sed quia consequuntur magn **Maldad**', Comment: '...'}


{Question: 'Lorem ipsum dolor sit amet **maltrato** consectetur adipiscing elit', Answer: '...', Alternative_answer: 'odit aut fugit, sed quia consequuntur magn **euforatis**', Comment: '...'}

我尝试过的代码如下:

1.-

    $match: {
        $text: {
            $search: filterBy,
            $caseSensitive: caseSensitive == "true",
            $diacriticSensitive: diacriticSensitive == "true",
        },
    },
};

首先我为每个字段创建了索引,但它无法正常工作。

2.- 我尝试过将案例分开,但也没有得到好的结果。

mandatoryWords.forEach((md) => {
    andQuery.push({
        $or: [
            {
                Question: {
                    $regex: md,
                    $options: "i",
                },
            },
            {
                Answer: {
                    $regex: md,
                    $options: "i",
                },
            },
            {
                Alternative_answer: {
                    $regex: md,
                    $options: "i",
                },
            },
            {
                Comment: {
                    $regex: md,
                    $options: "i",
                },
            },
        ],
    });
});

let orQuery = [];
filterWords.forEach((fw) => {
    orQuery.push(
        {
            Question: {
                $regex: fw,
                $options: "i",
            },
        },
        {
            Answer: {
                $regex: fw,
                $options: "i",
            },
        },
        {
            Alternative_answer: {
                $regex: fw,
                $options: "i",
            },
        },
        {
            Comment: {
                $regex: fw,
                $options: "i",
            },
        },
    );
});

// Check if there are mandatory and optional conditions
if (andQuery.length > 0 && orQuery.length > 0) {
    search = {
        $match: {
            $and: [
                ...andQuery, // Incorporates all mandatory conditions
                { $or: orQuery }, // Adds the condition that at least one optional word is present
            ],
        },
    };
} else if (andQuery.length > 0) {
    // Mandatory conditions only
    search = {
        $match: {
            $and: andQuery,
        },
    };
} else if (orQuery.length > 0) {
    // Optional conditions only
    search = {
        $match: {
            $or: orQuery,
        },
    };
}

mongodb vue.js mongoose
1个回答
0
投票
  1. 对于第一个要求,您需要确保搜索查询中的所有单词都出现在至少一个字段中。这可以通过为搜索查询中的每个单词创建一个带有
    $and
    $regex
    查询来实现。
  2. 对于第二个需求,需要区分完全匹配和部分匹配。这可以通过检查搜索查询是否用引号括起来来实现。如果是,您可以删除引号并搜索完全匹配的内容。如果不是,您可以搜索部分匹配。
let exactMatch = false;

// Check if the search query is enclosed in quotes
if (searchQuery.startsWith('"') && searchQuery.endsWith('"')) {
    // Remove the quotes
    searchQuery = searchQuery.substring(1, searchQuery.length - 1);
    exactMatch = true;
}

// Split the search query into words
let words = searchQuery.split(' ');

let andQuery = [];
words.forEach((word) => {
    let regex = exactMatch ? `^${word}$` : word;
    andQuery.push({
        $or: [
            { Question: { $regex: regex, $options: 'i' } },
            { Answer: { $regex: regex, $options: 'i' } },
            { Alternative_answer: { $regex: regex, $options: 'i' } },
            { Comment: { $regex: regex, $options: 'i' } },
        ],
    });
});

search = {
    $match: {
        $and: andQuery,
    },
};

此代码将为搜索查询中的每个单词创建一个

$and
查询,并带有
$regex
。如果搜索查询用引号括起来,它将搜索完全匹配的内容。否则,它将搜索部分匹配。
$options: 'i'
使搜索不区分大小写。

© www.soinside.com 2019 - 2024. All rights reserved.