Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOCSP-28393 C# new atlas search examples #521

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 97 additions & 3 deletions source/fundamentals/atlas-search.txt
Original file line number Diff line number Diff line change
@@ -80,11 +80,11 @@ categorizes data in a searchable format.
To learn how to create an Atlas Search Index see the
:atlas:`Create an Atlas Search Index </atlas-search/create-index>` Atlas guide.

Atlas Search Operators
----------------------
Atlas Search Operators and Collectors
-------------------------------------

The ``Search`` class contains methods you can use to perform ``$search``
operations. For a full list of available ``$search`` operators, see the :atlas:`Operators and Collectors
operations. For a full list of available ``$search`` operators and collectors, see the :atlas:`Operators and Collectors
</atlas-search/operators-and-collectors>` Atlas guide.

Autocomplete
@@ -250,6 +250,40 @@ The search returns the following documents:
To learn more about the ``exists`` operator, see the :atlas:`exists </atlas-search/exists>`
Atlas guide.

Facet
~~~~~

Use the ``Facet()`` method to group results by values or ranges in the specified faceted fields
and return the count for each of those groups.

You can use ``Facet()`` with both the ``$search`` and ``$searchMeta`` stages. MongoDB recommends using
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[s] Suggestion to include the term method here for consistency with the other sections, and also to differentiate from the other mentions of "using facet" when generally referring to the collector:

Suggested change
You can use ``Facet()`` with both the ``$search`` and ``$searchMeta`` stages. MongoDB recommends using
You can use the ``Facet()`` method with both the ``$search`` and ``$searchMeta`` stages. MongoDB recommends using

facet with the ``$searchMeta`` stage to retrieve metadata results only for the query.
To retrieve metadata results and query results using the ``$search`` stage, you must use the
``$$SEARCH_META`` aggregation variable. See :atlas:`SEARCH_META Aggregation Variable </atlas-search/facet/#std-label-fts-facet-aggregation-variable>` to learn more.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[s] Suggestion to revise (or something similar) based on the style guide:

Suggested change
``$$SEARCH_META`` aggregation variable. See :atlas:`SEARCH_META Aggregation Variable </atlas-search/facet/#std-label-fts-facet-aggregation-variable>` to learn more.
``$$SEARCH_META`` aggregation variable. To learn more about this variable, see the :atlas:`SEARCH_META Aggregation Variable </atlas-search/facet/#std-label-fts-facet-aggregation-variable>` section.


The following limitations apply:

- You can run facet queries on a single field only. You can't run facet queries on groups of fields.
- You can run facet queries over sharded collections on clusters running MongoDB v6.0 only.

The following example searches searches the ``guitars`` collection for any documents in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following example searches searches the ``guitars`` collection for any documents in
The following example searches the ``guitars`` collection for any documents in

which the value of the ``in_stock`` field is ``true``. The query uses the ``Facet()`` method to process the input documents, with a maximum number of ``100`` facet categories to return in the results. The query returns the total count of documents in which the value of ``in_stock`` is ``true``.

.. literalinclude:: /includes/fundamentals/code-examples/atlas-search/AtlasSearchExamples.cs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[q] Curious why the examples throughout this doc (not just in the diff) don't just use the io codeblock which is a bit cleaner? Or at least set copyable to false for the output maybe?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am also not sure because this is my first c# pr! I just followed the standard convention/what the rest of the examples had.

:start-after: // start-facet-search
:end-before: // end-facet-search
:language: csharp
:dedent:

The search returns the following result:

.. code-block:: none

4

To learn more about the ``facet`` collector, see the :atlas:`facet </atlas-search/facet>`
Atlas guide.

GeoShape
~~~~~~~~

@@ -683,3 +717,63 @@ The search returns the following document:

To learn more about the ``wildcard`` operator, see the :atlas:`wildcard </atlas-search/wildcard>`
Atlas guide.

Search Multiple Fields
----------------------

The ``path`` parameter is used by the Atlas Search
:atlas:`operators </atlas-search/query-syntax>` to specify the field or fields
to be searched. It may contain:

- A string
- An array of strings
- A :atlas:`multi analyzer </atlas-search/analyzers/multi>` specification
- An array containing a combination of strings and multi analyzer
specifications

.. note::

Not all operators can use all the different types of paths. See the
documentation for each individual operator for details on what types
of path it supports.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[s] Up to you but since this repeats most of the info from the guide, maybe can edit a bit and link to the guide for more information.


To search multiple indexed fields, use the ``Multi()`` method and pass in your fields. Documents which match on any of the specified fields are included in the result set. The following example searches the description and type fields.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[q] Are these references something different than make and description described in the next paragraph? Or are they the same and should they be monospace and should type be make?

Suggested change
To search multiple indexed fields, use the ``Multi()`` method and pass in your fields. Documents which match on any of the specified fields are included in the result set. The following example searches the description and type fields.
To search multiple indexed fields, use the ``Multi()`` method and pass in your fields. Documents which match on any of the specified fields are included in the result set. The following example searches the ``description`` and ``make`` fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch! it is the same. i will delete that sentence because it seems redundant with the following one


The following example searches for the string ``classic`` in either the ``make`` or the ``description`` field.

.. literalinclude:: /includes/fundamentals/code-examples/atlas-search/AtlasSearchExamples.cs
:start-after: // start-multiple-field-search
:end-before: // end-multiple-field-search
:language: csharp
:dedent:

The search returns the following documents:

.. code-block:: json

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 1946, "in_stock" : true, "rating" : 9}
{ "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 1902, "in_stock" : true, "rating" : 8}

Score Documents
---------------

Every document returned by an Atlas Search query is assigned a score based on relevance, and the documents included in a result set are returned in order from highest score to lowest. To learn more about how scores are assigned, see the :atlas:`score </atlas-search/scoring>` Atlas guide.

The score assigned to a returned document is part of the document's metadata. You can include each returned document's score along with the result set by using a ``$project`` stage in your aggregation pipeline.

The following example searches the ``guitars`` collection for documents in which the value of the ``make`` field contains exactly six letters and uses a ``$project`` stage to add a field named ``score`` to the returned documents.

.. literalinclude:: /includes/fundamentals/code-examples/atlas-search/AtlasSearchExamples.cs
:start-after: // start-score-search
:end-before: // end-score-search
:language: csharp
:dedent:

The search returns the following documents:

.. code-block:: json

{ "_id" : 1, "make" : "Fender", "description" : "Classic guitars known for their versatility.", "establishedYear" : 0, "in_stock" : false, "rating" : null, "score" : 1.0 }
{ "_id" : 4, "make" : "Kiesel", "description" : "Quality guitars made only for custom orders.", "establishedYear" : 0, "in_stock" : false, "rating" : null, "score" : 1.0 }
{ "_id" : 5, "make" : "Ibanez", "description" : "Well-crafted guitars used by many professional guitarists.", "establishedYear" : 0, "in_stock" : false, "rating" : null, "score" : 1.0 }
{ "_id" : 2, "make" : "Gibson", "description" : "Classic guitars known for their rich, full tones.", "establishedYear" : 0, "in_stock" : false, "rating" : null, "score" : 1.0 }
Original file line number Diff line number Diff line change
@@ -87,6 +87,19 @@ public static List<Guitar> ExistsSearch()
return result;
}

public static int FacetSearch()
{
// start-facet-search
var result = guitarsCollection.Aggregate()
.SearchMeta(Builders<Guitar>.Search.Facet(
Builders<Guitar>.Search.Equals(g => g.InStock, true),
Builders<Guitar>.SearchFacet.String("string", g => g.Make, 100)),
indexName: "guitarfacetsearch").Single().Facet["string"].Buckets.Count();
// end-facet-search

return result;
}

public static List<Guitar> GeoShapeSearch()
{
// start-geoshape-search
@@ -263,16 +276,46 @@ public static List<Guitar> WildcardSearch()
return result;
}

public static List<Guitar> MultipleFieldSearch()
{
// start-multiple-field-search
var result = guitarsCollection.Aggregate().Search(
Builders<Guitar>.Search.Phrase(Builders<Guitar>.SearchPath
.Multi(g => g.Description, g => g.Make), "classic"), indexName: "guitarmulti")
.ToList();
// end-multiple-field-search

return result;
}

public static List<Guitar> ScoreSearch()
{
// start-score-search
var regex = "[A-Za-z]{6}";

var result = guitarsCollection.Aggregate()
.Search(Builders<Guitar>.Search.Regex(g => g.Make, regex, allowAnalyzedField: true), indexName: "guitarscore")
.Project<Guitar>(Builders<Guitar>.Projection
.Include("Id")
.Include("Make")
.Include("Description")
.MetaSearchScore(g => g.Score))
.ToList();
// end-score-search

return result;
}

private static void Setup()
{
// This allows automapping of the camelCase database fields to our models.
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

// Establish the connection to MongoDB and get the restaurants database
// Establish the connection to MongoDB and get the guitars database
var mongoClient = new MongoClient(_mongoConnectionString);
var restaurantsDatabase = mongoClient.GetDatabase("sample_guitars");
guitarsCollection = restaurantsDatabase.GetCollection<Guitar>("guitars");
var guitarsDatabase = mongoClient.GetDatabase("sample_guitars");
guitarsCollection = guitarsDatabase.GetCollection<Guitar>("guitars");
}
}

@@ -292,6 +335,7 @@ public class Guitar
[BsonElement("in_stock_location")]
public Location InStockLocation { get; set; }
public int? Rating { get; set; }
public double Score {get; set;}
}

public class Location