Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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
Node.js 使用Mongodb进行自定义搜索_Node.js_Mongodb_Mongodb Atlas Search - Fatal编程技术网

Node.js 使用Mongodb进行自定义搜索

Node.js 使用Mongodb进行自定义搜索,node.js,mongodb,mongodb-atlas-search,Node.js,Mongodb,Mongodb Atlas Search,我有一个MongoDB作为我的数据库,后端写在node.js中。我试图实现一个表的搜索,该表返回所有输入字符串并匹配字符串的结果 例如,搜索“foo”将返回(按该顺序) 富美慕 doo foo doo//单词搜索的顺序并不重要,只要它将单词搜索放在第一位 福巴 福布 目前我有这个功能,但我相信有一种更好的方法可以做到这一点,而无需搜索数据库两次: async function(req, res) { var customerName = req.params

我有一个MongoDB作为我的数据库,后端写在node.js中。我试图实现一个表的搜索,该表返回所有输入字符串并匹配字符串的结果

例如,搜索“foo”将返回(按该顺序)

  • 富美慕

  • doo foo doo//单词搜索的顺序并不重要,只要它将单词搜索放在第一位

  • 福巴

  • 福布

目前我有这个功能,但我相信有一种更好的方法可以做到这一点,而无需搜索数据库两次:


    async function(req, res) {
        var customerName = req.params.customerName;
   //word match
        var customers1 = await Models.DummyContactTable.find({
            customerName: {
                $regex: "^" + customerName,
                $options: 'i'
            },
            IsActive: true
        });
    //String match
   
     var customers2 = await Models.DummyContactTable.find({
          $and: [
              {
                customerName: {
                  $regex: customerName, $options: 'i'
                }
              },
              {
                customerName: {
                  $not: {
                    $regex: "^" + customerName,
                  }
                },
                IsActive: true
              }
          ]
        });
    //Since sometimes we get duplicates, doing a filter and find to de-dup
      var customers = customers1.concat(customers2.filter((customer) => !customers1.find(f => f.uuid === customer.uuid)));

如果您需要这些排序规则,我会将您所有的客户名称加载到一个应用程序中,该应用程序会进行搜索,并完全在应用程序中执行搜索和排序。我甚至不希望Atlas搜索提供这种灵活性


(我认为您提供的查询也没有达到您想要的顺序。)

如果您使用Atlas Search,您可以编写如下查询:

{ 
  $search: {
    autocomplete: { 
      path: "customerName",
      query: "foo"
}}}

// atlas search index definition
{
  "mappings": {
    "fields": {
      "customerName" : { 
        "type" : "autocomplete"
}}}
如果需要控制结果分数,可以使用
composite

{
  $search: {
    compound: {
      should: [ 
        {autocomplete: {path: "customerName", query: "foo" }},
        {text: {path: "customerName", query: "foo" , score: { boost: { "value" : 3" }}}}
    ]}}}
在本例中,我们使用
text
操作符使用
lucene.standard
分析器在单词边界上进行拆分,并将这些结果提升到上面。Atlas搜索的结果会自动按分数排序,结果排在第一位。查询已针对性能进行了优化,此查询将一次性完成


根据您的排序和查询需要(例如使用不同的分析器、前缀搜索、短语搜索、正则表达式等),还有许多其他旋钮需要打开.

将用户输入用作正则表达式是一个安全漏洞。在将用户输入发送到db之前,我最终会将检查添加到用户输入中,但对于此演示代码,我只想获得正确的搜索结果。您是否在客户名称上设置了文本索引?类似的问题通常可以通过ngrams解决。你看过Mongodb Atlas搜索吗?您可以使用autocomplete操作符一次快速返回所有结果。只是花了些时间研究这个。如果你能提供一个工作样本就好了。如果可能的话,我可以快速尝试看看这是否可行,否则我将不得不做大量的尝试和错误,看看什么可行。前两个的顺序不重要,因为它们可以互换,重要的是“单词”出现在句子之前,如果是这种情况,请更新您的问题,以明确说明要求。