【问题标题】:Autocomplete filtered with mongodb使用 mongodb 过滤的自动完成功能
【发布时间】:2021-02-06 16:11:46
【问题描述】:

我想对 name 执行自动补全,但使用 mongoose 和 nodejs 在特定城市进行过滤。 我有一个这样的 mongodb 集合:

{
    "_id" : ObjectId("6007fd9d984e2507ad452cf3"),
    "name" : "John",
    "city" : "A",
},
{
    "_id" : ObjectId("6007ff6844d9e517e1ec0976"),
    "name" : "Jack",
    "city" : "B",
}

到目前为止我做了什么:

我已经使用搜索索引设置了 MongoDB Atlas(在 search doc 的帮助下) 并像这样设置自动完成:

router.get('/search', async (request, response) => {
  try {
    let result = await Client.aggregate([
      {
        "$search": {
          "autocomplete": {
            "query": `${request.query.term}`,
            "path": "name",
            "fuzzy": {
              "maxEdits": 2,
              "prefixLength": 3,
            },
          },
        },
      },
      {
        $limit: 3
      },
      {
        $project: {
          "_id": 0,
        }
      }
    ]);
    response.send(result);
  } catch (e) {
    response.status(500).send({message: e.message});
  }
});

在前端,autocompleteJs

  const autoCompleteJS = new autoComplete({
    data: {
      src: async () => {
        const query = document.querySelector("#autoComplete").value;
        const source = await fetch(`${window.location.origin}/search?term=${query}`);
        const data = await source.json();
        return data;
      },
      key: ["name"],
    },
    trigger: {
      event: ["input", "focus"],
    },
    searchEngine: "strict",
    highlight: true,
  });

到目前为止,它运行良好。但我不知道如何根据城市过滤自动完成结果。 documentation 似乎没有提到这一点。你有什么线索吗?

【问题讨论】:

    标签: node.js mongodb mongoose autocomplete mongodb-atlas-search


    【解决方案1】:

    在执行搜索后使用aggregation pipeline 中的$where 管道阶段过滤掉不需要的文档。比如,

    Client.aggregate([
      {
        "$search": {
          "autocomplete": {
            "query": `${request.query.term}`,
            "path": "name",
            "fuzzy": {
              "maxEdits": 2,
              "prefixLength": 3,
            },
          },
        },
      },
      { 
        $match: { city: 'city-name' } 
      },
      {
        $limit: 3
      },
      {
        $project: {
          "_id": 0,
        }
      }
    ]);
    

    【讨论】:

    • 谢谢保罗!与 $match 配合得很好 :)
    【解决方案2】:

    像这样使用compound 运算符,让您以高效的方式更好地控制结果:

    "$search": {
      "compound" : {
        "filter" : [{ 
           "text" : { path: "city", query: "New York" } 
         }],
         "must": [{ 
              "autocomplete": {
                "query": `${request.query.term}`,
                "path": "name",
                "fuzzy": {
                  "maxEdits": 2,
                  "prefixLength": 3,
                },
              },}
            }] }
    

    使用filter 将过滤您的结果,而不会影响分数。 must 将要求 name 字段也将匹配。另请查看compound 文档中的shouldmustNot 以了解更多选项。

    【讨论】:

    • 谢谢道格!但不幸的是,我不知道为什么——使用“过滤器”。结果返回给我一个空数组:/(也许过滤器与自动完成不兼容?)
    猜你喜欢
    • 1970-01-01
    • 2022-10-24
    • 2022-08-15
    • 2015-07-05
    • 2016-11-10
    • 2016-07-15
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    相关资源
    最近更新 更多