MongoDB: Perform a text-search in a document field

2019-09-14 15:40发布

It may be related to this question Basic GROUP BY statement using OPA MongoDB high level API.

I want to be able to retrieve a list of documents which "name" field value contains a given string.

Here's my documents list :

{name: "Charles-Hugo"}, {name: "Jean Pierre"}, {name: "Pierre Dupont"},

I want to be able to only retrieve documents which name contains the "Pierre" string: Jean Pierre, and Pierre Dupont.

I know this isn't possible with the MongoDB high-level API. I've looked in the low-level API functions but I don't know what's the easiest way to retrieve my documents in safe Opa type.

Also I'd like to add skip/limit options to my query.

Any idea ?

标签: mongodb opa
2条回答
ゆ 、 Hurt°
2楼-- · 2019-09-14 16:14

As @Henri pointed out there is regular expression searching support in Opa since commit [enhance] DbGen: add case insensitive regex operator =~ what is very nice.

Mind that it is using $regex operator, not the full-text index and it may result with some performance loss :( As MongoDB documentation says $regex operator uses indexes in limited way - only for prefix search: pattern ^Jean. Searching for Jean anywhere in text will require full scan.

Personally, I am using full-text index feature of Mongo with Opa's "low-level" API for the $text command like this:

  function list({float score, Article.id id}) textSearch(string query) {
    function onfailure(failure) {
      cat.error("textSearch({{~query}}): {failure}");
      [];
    }
    function onsuccess(success) {
      function aux(~{name,value}) {
        name == "results";
      }
      match (List.filter(aux, success)) {
      | [] :
        // `results` field not found - error
        onfailure(success);
      | results:
        cat.debug("textSearch({~{query}}): {results}");
        function ({~score, obj: ~{id}}) {
          ~{score, id}
        }
        |> List.map(_, Bson.doc2opa(results) ? []);
      }
    }

    opts = [H.str("search", query), H.doc("project", [H.i32("_id",0), H.i32("id",1)])];
    //  { search: query, project: {_id:0, id:1}, }
    //  |> Bson.opa2doc
    outcome = MongoCommands.simple_str_command_opts(ll_db, db_name, "text", coll_name, opts);
    MongoCommon.outcome_map(outcome, onsuccess, onfailure)
  }

Feature is available in Mongo since 2.4 as experimental (you have to turn it on by special configuration option) and in 2.6 as stable (turned on by default).

查看更多
放我归山
3楼-- · 2019-09-14 16:25

The DbGen automation mechanism in Opa has support for this:

DbSet.iterator(/path/data[name =~ pattern])
查看更多
登录 后发表回答